<?php declare(strict_types=1);
namespace Shopware\B2B\Address\BridgePlatform;
use Shopware\B2B\Common\IdValue;
use Shopware\B2B\Common\Repository\NotFoundException;
use Shopware\B2B\Debtor\Framework\DebtorRepositoryInterface;
use Shopware\B2B\StoreFrontAuthentication\Framework\AuthenticationService;
use Shopware\Core\Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressDefinition;
use Shopware\Core\Checkout\Customer\CustomerEvents;
use Shopware\Core\Checkout\Customer\Event\CustomerLoginEvent;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class AddressSynchronizationSubscriber implements EventSubscriberInterface
{
private const SUBSCRIBER_PRIORITY = -10;
/**
* @var CustomerAddressDataService
*/
private $customerAddressDataService;
/**
* @var AuthenticationService
*/
private $authenticationService;
/**
* @var EntityRepositoryInterface
*/
private $customerRepository;
/**
* @var DebtorRepositoryInterface
*/
private $debtorRepository;
public function __construct(
CustomerAddressDataService $customerAddressDataService,
AuthenticationService $authenticationService,
EntityRepositoryInterface $customerRepository,
DebtorRepositoryInterface $debtorRepository
) {
$this->customerAddressDataService = $customerAddressDataService;
$this->authenticationService = $authenticationService;
$this->customerRepository = $customerRepository;
$this->debtorRepository = $debtorRepository;
}
public static function getSubscribedEvents(): array
{
return [
CustomerEvents::CUSTOMER_ADDRESS_WRITTEN_EVENT => 'syncAddressesByAddressWritten',
CustomerLoginEvent::class => ['syncAddressesByCustomerLogin', self::SUBSCRIBER_PRIORITY],
];
}
public function syncAddressesByCustomerLogin(CustomerLoginEvent $event): void
{
if (!$this->authenticationService->isB2b()) {
return;
}
$customer = $event->getCustomer();
$this->customerAddressDataService
->synchronizeCustomerAddresses($customer);
}
public function syncAddressesByAddressWritten(EntityWrittenEvent $event): void
{
if ($event->getEntityName() !== CustomerAddressDefinition::ENTITY_NAME) {
return;
}
$writtenResults = $event->getPayloads();
$customerIds = [];
foreach ($writtenResults as $address) {
$customerId = $address['customerId'];
try {
$this->debtorRepository->fetchOneById(IdValue::create($customerId));
} catch (NotFoundException $exception) {
continue;
}
$customerIds[] = $customerId;
}
if (!$customerIds) {
return;
}
$result = $this->customerRepository
->search(new Criteria($customerIds), $event->getContext());
foreach ($result->getEntities() as $entity) {
$this->customerAddressDataService
->synchronizeCustomerAddresses($entity);
}
}
}