<?php
declare(strict_types=1);
namespace NetInventors\NetiNextAdminTools\Subscriber;
use NetInventors\NetiNextAdminTools\Core\FlowTrigger\NetiNextAdminToolsCustomerActivatedEvent;
use NetInventors\NetiNextAdminTools\Core\FlowTrigger\NetiNextAdminToolsCustomerDeactivatedEvent;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Checkout\Customer\CustomerEvents;
use Shopware\Core\Framework\Context;
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\EqualsAnyFilter;
use Shopware\Core\System\SalesChannel\Context\AbstractSalesChannelContextFactory;
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextService;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CustomerSubscriber implements EventSubscriberInterface
{
private EventDispatcherInterface $eventDispatcher;
private EntityRepositoryInterface $customerRepository;
private AbstractSalesChannelContextFactory $salesChannelContextFactory;
public function __construct(
EventDispatcherInterface $eventDispatcher,
EntityRepositoryInterface $customerRepository,
AbstractSalesChannelContextFactory $salesChannelContextFactory
) {
$this->eventDispatcher = $eventDispatcher;
$this->customerRepository = $customerRepository;
$this->salesChannelContextFactory = $salesChannelContextFactory;
}
public static function getSubscribedEvents(): array
{
return [
CustomerEvents::CUSTOMER_WRITTEN_EVENT => 'onCustomerWritten',
];
}
public function onCustomerWritten(EntityWrittenEvent $event): void
{
$payloads = $event->getPayloads();
$context = $event->getContext();
$customerIds = [];
/** @var array<string, Context> $languageContexts */
$languageContexts = [];
$languageContexts[$context->getLanguageId()] = $context;
/** @var array<string, mixed> $payload */
foreach ($payloads as $payload) {
if (!isset($payload['active'], $payload['id'])) {
continue;
}
$customerIds[] = (string)$payload['id'];
}
if ([] === $customerIds) {
return;
}
$customers = $this->getCustomersById($customerIds, $context);
if ([] === $customers) {
return;
}
/** @var CustomerEntity $customer */
foreach ($customers as $customer) {
if (!$customer instanceof CustomerEntity) {
continue;
}
$customersLanguageId = $customer->getLanguageId();
if (!isset($languageContexts[$customersLanguageId])) {
$salesChannelContext = $this->salesChannelContextFactory->create(
'',
$customer->getSalesChannelId(),
[ SalesChannelContextService::LANGUAGE_ID => $customersLanguageId ]
);
$languageContexts[$customersLanguageId] = $salesChannelContext->getContext();
}
//if it is true, then the customer was fetched with the wrong language id
if ($context->getLanguageId() !== $customersLanguageId) {
$criteria = new Criteria([ $customer->getId() ]);
$criteria->addAssociation('salutation');
//loading customer again for the correct salutation
/** @var CustomerEntity $customer */
$customer =
$this->customerRepository->search($criteria, $languageContexts[$customersLanguageId])->first();
}
if ($customer->getActive()) {
$this->eventDispatcher->dispatch(
new NetiNextAdminToolsCustomerActivatedEvent(
$languageContexts[$customersLanguageId], $customer, $customer->getSalesChannelId()
)
);
} else {
$this->eventDispatcher->dispatch(
new NetiNextAdminToolsCustomerDeactivatedEvent(
$languageContexts[$customersLanguageId],
$customer,
$customer->getSalesChannelId()
)
);
}
}
}
private function getCustomersById(array $customerIds, Context $context): array
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsAnyFilter('id', $customerIds));
$criteria->addAssociation('salutation');
return $this->customerRepository->search($criteria, $context)->getElements();
}
}