<?php declare(strict_types=1);
namespace Tonur\Packstation\Subscriber;
use Psr\Log\LoggerAwareTrait;
use Shopware\Core\Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressCollection;
use Shopware\Core\Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressDefinition;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\System\Country\CountryCollection;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Event\StorefrontRenderEvent;
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\Register\CheckoutRegisterPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Checkout\Customer\CustomerEvents;
use Tonur\Packstation\Checkout\Packstation\PackstationEntity;
use Tonur\Packstation\Service\PackstationService;
use Tonur\Packstation\TonurPackstation6;
class PackstationSubscriber implements EventSubscriberInterface
{
/**
* @var SystemConfigService
*/
private $systemConfigService;
/**
* @var PackstationService
*/
private $packstationService;
/**
* @var EntityRepositoryInterface
*/
private $countryRepository;
use LoggerAwareTrait;
/**
* @param SystemConfigService $systemConfigService
* @param PackstationService $packstationService
* @param EntityRepositoryInterface $countryRepository
*/
public function __construct(
SystemConfigService $systemConfigService,
PackstationService $packstationService,
EntityRepositoryInterface $countryRepository
)
{
$this->systemConfigService = $systemConfigService;
$this->packstationService = $packstationService;
$this->countryRepository = $countryRepository;
}
public static function getSubscribedEvents(): array
{
return [
StorefrontRenderEvent::class => 'onStorefrontRender',
CustomerEvents::CUSTOMER_ADDRESS_WRITTEN_EVENT => 'onCustomerAddressWritten',
AddressListingPageLoadedEvent::class => 'onAddressListingPageLoaded',
AddressDetailPageLoadedEvent::class => 'onAddressDetailPageLoaded',
CheckoutRegisterPageLoadedEvent::class => 'onCheckoutRegisterPageLoaded',
AccountLoginPageLoadedEvent::class => 'onAccountLoginPageLoaded'
];
}
public function onStorefrontRender(StorefrontRenderEvent $event)
{
if (!$this->isPluginActive($event->getSalesChannelContext()->getSalesChannel()->getId())) {
return;
}
$config = $this->systemConfigService->get(TonurPackstation6::BUNDLE_NAME . '.config');
$event->setParameter('repertusPackstationConfig', $config);
}
/**
* @param EntityWrittenEvent $event
* @throws \Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException
*/
public function onCustomerAddressWritten(EntityWrittenEvent $event): void
{
if (!$this->isPluginActive() ||
$event->getEntityName() !== CustomerAddressDefinition::ENTITY_NAME) {
return;
}
foreach ($event->getWriteResults() as $writeResult) {
$customerAddress = $writeResult->getPayload();
$packstationInfo = $this->packstationService->getPackstationInfo($customerAddress, $event->getContext());
$this->logger->debug(__METHOD__, ['packstationInfo' => $packstationInfo, 'customerAddress' => $customerAddress]);
if ($packstationInfo !== false) {
$this->packstationService->savePackstation(
$packstationInfo,
$event->getContext()
);
} else if ($this->addressContainsMainData($customerAddress)) {
$this->packstationService->deletePackstationByAddressId($customerAddress['id'], $event->getContext());
}
}
}
public function onAddressListingPageLoaded(AddressListingPageLoadedEvent $event)
{
if (!$this->isPluginActive($event->getSalesChannelContext()->getSalesChannel()->getId())) {
return;
}
$request = $event->getRequest();
$changeableAddresses = $request->get('changeableAddresses');
$isChangeBilling = \is_array($changeableAddresses) && array_key_exists('changeBilling', $changeableAddresses) ? $changeableAddresses['changeBilling'] : null;
$page = $event->getPage();
$extensions = $page->getExtensions();
$extensions['tonurPackstationCountryUuidGermany'] = $this->getCountryUuidByIso($event->getContext());
if ($isChangeBilling) {
$filteredAddresses = new CustomerAddressCollection();
$userAddresses = $page->getAddresses();
foreach ($userAddresses as $address) {
$packstationExtension = $address->getExtension('repertusPackstation');
if ($packstationExtension instanceof PackstationEntity) {
continue;
}
$filteredAddresses->add($address);
}
$page->setAddresses($filteredAddresses);
$extensions['tonurPackstationHasPackstationAddresses'] = $filteredAddresses->count() < $userAddresses->count();
}
$page->setExtensions($extensions);
}
public function onAddressDetailPageLoaded(AddressDetailPageLoadedEvent $event)
{
if (!$this->isPluginActive($event->getSalesChannelContext()->getSalesChannel()->getId())) {
return;
}
$page = $event->getPage();
$extensions = $page->getExtensions();
$extensions['tonurPackstationCountryUuidGermany'] = $this->getCountryUuidByIso($event->getContext());
$page->setExtensions($extensions);
}
public function onCheckoutRegisterPageLoaded(CheckoutRegisterPageLoadedEvent $event)
{
if (!$this->isPluginActive($event->getSalesChannelContext()->getSalesChannel()->getId())) {
return;
}
$page = $event->getPage();
$extensions = $page->getExtensions();
$extensions['tonurPackstationCountryUuidGermany'] = $this->getCountryUuidByIso($event->getContext());
$page->setExtensions($extensions);
}
public function onAccountLoginPageLoaded(AccountLoginPageLoadedEvent $event)
{
if (!$this->isPluginActive($event->getSalesChannelContext()->getSalesChannel()->getId())) {
return;
}
$page = $event->getPage();
$extensions = $page->getExtensions();
$extensions['tonurPackstationCountryUuidGermany'] = $this->getCountryUuidByIso($event->getContext());
$page->setExtensions($extensions);
}
private function getCountryUuidByIso($context, $iso = 'DE')
{
$criteria = (new Criteria())
->addFilter(new EqualsFilter('country.active', true))
->addFilter(new EqualsFilter('country.iso', $iso));
/** @var CountryCollection $countries */
$countries = $this->countryRepository->search($criteria, $context)->getEntities();
$country = $countries->first();
return $country ? $country->getId() : null;
}
private function isPluginActive(?string $salesChannelId = null)
{
return $this->systemConfigService->get(TonurPackstation6::BUNDLE_NAME . '.config.pluginActive', $salesChannelId);
}
private function addressContainsMainData($customerAddress)
{
return array_key_exists('customerId', $customerAddress) &&
array_key_exists('street', $customerAddress) &&
array_key_exists('zipcode', $customerAddress) &&
array_key_exists('city', $customerAddress) &&
array_key_exists('countryId', $customerAddress) &&
array_key_exists('firstName', $customerAddress) &&
array_key_exists('lastName', $customerAddress);
}
}