<?php declare(strict_types=1);
namespace Compra\EsiSW6\Export\Subscriber;
use Compra\EsiSW6\Core\System\Service\ApiService;
use Shopware\Core\Checkout\Customer\CustomerEvents;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CustomerSubscriber implements EventSubscriberInterface
{
protected EntityRepository $customerRepo;
protected EntityRepository $customerAddressRepo;
protected ApiService $apiService;
public const RELEVANT_CUSTOMER_FIELDS = [
'salutationId',
'firstName',
'lastName',
'company',
'email',
'birthday'
];
/** @var array */
public const RELEVANT_ADDRESS_FIELDS = [
'countryId',
'countryStateId',
'company',
'department',
'salutationId',
'title',
'firstName',
'lastName',
'street',
'zipcode',
'city',
'vatId',
'phoneNumber',
'additionalAddressLine1',
'additionalAddressLine2',
];
public function __construct(
EntityRepository $customerRepo,
EntityRepository $customerAddressRepo,
ApiService $apiService
) {
$this->customerRepo = $customerRepo;
$this->customerAddressRepo = $customerAddressRepo;
$this->apiService = $apiService;
}
/**
* @return string[]
*/
public static function getSubscribedEvents(): array
{
return [
CustomerEvents::CUSTOMER_WRITTEN_EVENT => 'onCustomerWritten',
CustomerEvents::CUSTOMER_ADDRESS_WRITTEN_EVENT => 'onCustomerAddressWritten',
];
}
/**
* mark the customer as to be exported when there are relevant changes
*
* @param EntityWrittenEvent $event
*/
public function onCustomerWritten(EntityWrittenEvent $event): void
{
$payloads = $event->getPayloads();
$admin = $this->apiService->getAdminUser($event->getContext());
foreach ($payloads as $payload) {
if ($admin !== ApiService::ESI_API_USER && $this->isRelevantCustomerChange($payload)) {
$data = [
'id' => $payload['id'],
'customFields' => [
'compra_esi_xml_export' => true,
],
];
$this->customerRepo->update([$data], $event->getContext());
}
}
}
/**
* mark the customer address as to be exported when there are relevant changes
*
* @param EntityWrittenEvent $event
*/
public function onCustomerAddressWritten(EntityWrittenEvent $event): void
{
$payloads = $event->getPayloads();
$admin = $this->apiService->getAdminUser($event->getContext());
foreach ($payloads as $payload) {
if ($admin !== ApiService::ESI_API_USER && $this->isRelevantAddressChange($payload)) {
$extend = [
'id' => $payload['id'],
'customerId' => $payload['customerId'], // added customer number to fix error thrown by B2B suite due to missing test
'customFields' => ['compra_esi_xml_export' => true],
];
$updateData = $this->customerAddressRepo->update([$extend], $event->getContext());
$extend = [
'id' => $payload['customerId'],
'customFields' => [
'compra_esi_xml_export_address' => true,
],
];
$updateData = $this->customerRepo->update([$extend], $event->getContext());
}
}
}
/**
* Only some changes are interesting for the export.
* For example a change on the last login is not interesting. Especially we need to avoid an endless loop when saving the export custom field marker.
*
* @param $payload
* @return bool
*/
private function isRelevantCustomerChange($payload): bool
{
if (!isset($payload['id'])
|| empty($payload['id'])
|| empty(\array_intersect(self::RELEVANT_CUSTOMER_FIELDS, \array_keys($payload)))) {
return false;
}
return true;
}
/**
* Only some changes are interesting for the export.
* For example a change on the last login is not interesting. Especially we need to avoid an endless loop when saving the export custom field marker.
*
* @param $payload
* @return bool
*/
private function isRelevantAddressChange($payload): bool
{
if (!isset($payload['id'])
|| empty($payload['id'])
|| empty(\array_intersect(self::RELEVANT_ADDRESS_FIELDS, \array_keys($payload)))) {
return false;
}
return true;
}
}