<?php declare(strict_types=1);
namespace FourtwosixPhoneValidation\Subscriber;
use FourtwosixPhoneValidation\Service\Routes\CustomerAddressRoute;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Core\System\Country\CountryEntity;
use Shopware\Storefront\Page\Account\Login\AccountLoginPageLoadedEvent;
use Shopware\Storefront\Page\Address\Detail\AddressDetailPageLoadedEvent;
use Shopware\Storefront\Page\Address\Listing\AddressListingPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Register\CheckoutRegisterPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class AddCountryPhonePrefixSubscriber implements EventSubscriberInterface
{
protected EntityRepositoryInterface $countryRepository;
protected EntityRepositoryInterface $customerAddressRepository;
protected CustomerAddressRoute $customerAddressRoute;
/**
* @param EntityRepositoryInterface $countryRepository
* @param EntityRepositoryInterface $customerAddressRepository
* @param CustomerAddressRoute $customerAddressRoute
*/
public function __construct(
EntityRepositoryInterface $countryRepository,
EntityRepositoryInterface $customerAddressRepository,
CustomerAddressRoute $customerAddressRoute
) {
$this->countryRepository = $countryRepository;
$this->customerAddressRepository = $customerAddressRepository;
$this->customerAddressRoute = $customerAddressRoute;
}
/**
* @return string[]
*/
public static function getSubscribedEvents(): array
{
return [
CheckoutRegisterPageLoadedEvent::class => 'onCheckoutRegisterPageLoadedEvent',
AccountLoginPageLoadedEvent::class => 'onAccountLoginPageLoadedEvent',
AddressDetailPageLoadedEvent::class => 'onAddressDetailPageLoadedEvent',
AddressListingPageLoadedEvent::class => 'onAddressListingPageLoadedEvent',
];
}
/**
* @param $event
* @param array $ftsPRefixes
* @return void
*/
protected function addCountryExtension($event, array $ftsPRefixes = []): void
{
$countries = [];
// We retrieve only country with custom field set sorted by ISO code (which will be prepended in twig)
$criteria = new Criteria();
$criteria->addSorting(new FieldSorting('iso'));
$criteria->addFilter(
new NotFilter(
MultiFilter::CONNECTION_AND,
[
new EqualsFilter('customFields.fourtwosix_phone_country_prefix', null),
]
)
);
$countryEntities = $this->countryRepository->search($criteria, $event->getContext())->getEntities();
/** @var CountryEntity $countryEntity */
foreach ($countryEntities as $countryEntity) {
$countryCustomFields = $countryEntity->getTranslated()["customFields"] ?? null;
if (is_null($countryCustomFields)) {
continue;
}
$prefixes = $countryCustomFields["fourtwosix_phone_country_prefix"] ?? null;
if (is_null($prefixes)) {
continue;
}
// In cases like '+39,' we do not want ['+39', '']
$explodedePrefixes = array_filter(explode(",", $prefixes));
// For cases like '+421, ' we do not want ['+421', ' ']
$trimmedPrefixes = array_filter(
array_map(function ($prefix) {
return trim($prefix);
}, $explodedePrefixes)
);
// add each prefix in a separate line to use just a plain for loop in twig
foreach ($trimmedPrefixes as $trimmedPrefix) {
$countries[] = [
"iso" => $countryEntity->getIso(),
"prefix" => $trimmedPrefix,
];
}
}
$data = [
"countries" => $countries,
"fts_prefixes" => $ftsPRefixes,
];
$event->getPage()->addExtension(
"FourtwosixPhoneNumberCountryPrefix",
new ArrayStruct($data)
);
}
/**
* Checkout registration -> does not need to load customer
* @param CheckoutRegisterPageLoadedEvent $event
* @return void
*/
public function onCheckoutRegisterPageLoadedEvent(CheckoutRegisterPageLoadedEvent $event): void
{
$this->addCountryExtension($event);
}
/**
* Login/Registration -> does not need to load customer
* @param AccountLoginPageLoadedEvent $event
* @return void
*/
public function onAccountLoginPageLoadedEvent(AccountLoginPageLoadedEvent $event): void
{
$this->addCountryExtension($event);
}
/**
* Address created/updated from page not AJAX like in Profile Overview or in checkout/confirm
* @param AddressDetailPageLoadedEvent $event
* @return void
*/
public function onAddressDetailPageLoadedEvent(AddressDetailPageLoadedEvent $event): void
{
$address = $event->getPage()->getAddress();
$salesChannelContext = $event->getSalesChannelContext();
$context = $salesChannelContext->getContext();
if (is_null($address)) {
// Create new address -> fetch data from customer
$customer = $salesChannelContext->getCustomer();
if (is_null($customer)) {
return;
}
$customerId = $customer->getId();
$ftsPrefixes = $this->customerAddressRoute->getCustomerAddressPrefixFromCustomer($customerId, $context);
} else {
// Edit address -> fetch data from customerAddressId
$addressid = $address->getId();
$ftsPrefixes = $this->customerAddressRoute->getCustomerAddressPrefixFromAddressId($addressid, $context);
}
$this->addCountryExtension($event, $ftsPrefixes);
}
/**
* @param AddressListingPageLoadedEvent $event
* @return void
*/
public function onAddressListingPageLoadedEvent(AddressListingPageLoadedEvent $event): void
{
$salesChannelContext = $event->getSalesChannelContext();
$customerId = $salesChannelContext->getCustomer()->id;
$context = $salesChannelContext->getContext();
// Load customerAddressPrefixes
$ftsPrefixes = $this->customerAddressRoute->getCustomerAddressPrefixFromCustomer($customerId, $context);
$this->addCountryExtension($event, $ftsPrefixes);
}
}