<?php declare(strict_types=1);
namespace Nd\Srs\Subscriber;
use Nd\Srs\Service\CustomerCommunicator;
use Shopware\Core\Content\Seo\SeoUrlUpdater;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityDeletedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\Uuid\Exception\InvalidUuidException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CustomerSubscriber implements EventSubscriberInterface{
protected EntityRepositoryInterface $customerRepository;
protected CustomerCommunicator $customerCommunicator;
public function __construct(EntityRepositoryInterface $customerRepository, CustomerCommunicator $customerCommunicator){
$this->customerRepository = $customerRepository;
$this->customerCommunicator = $customerCommunicator;
}
public static function getSubscribedEvents(): array
{
return [
'customer.written' => 'onCustomerEntityWritten',
'customer_address.written' => 'onCustomerAddressEntityWritten'
];
}
public function onCustomerAddressEntityWritten(EntityWrittenEvent $event): void
{
$payload = $event->getPayloads()[0];
if(count($event->getWriteResults()) == 0){
return;
}
if(!array_key_exists("updatedAt", $payload) || !array_key_exists("customerId", $payload) || !array_key_exists("street", $payload)){
return;
}
$customerId = $payload["customerId"];
$customer = $this->retrieveCustomer($customerId, $event->getContext());
if(!$customer){
return;
}
if($event->getWriteResults()[0]->getOperation() == "update"){
if($customer->getDefaultBillingAddressId() == $payload["id"]){
if($payload['firstName'] != $customer->getFirstName() || $payload['lastName'] != $customer->getLastName()){
$data = ['id' => $customer->getId(), "firstName" => $payload['firstName'], "lastName" => $payload['lastName']];
$this->customerRepository->upsert([$data], $event->getContext());
return; // This one also triggers the complete flow
}
$this->customerCommunicator->updateCurrentSrsCustomer($customer, $event->getContext());
}
}
}
public function onCustomerEntityWritten(EntityWrittenEvent $event): void
{
$payload = $event->getPayloads()[0];
if(count($event->getWriteResults()) == 0){
return;
}
$customerId = $event->getWriteResults()[0]->getPrimaryKey();
$customer = $this->retrieveCustomer($customerId, $event->getContext());
if(!$customer){
return;
}
if($event->getWriteResults()[0]->getOperation() == "insert"){
$this->customerCommunicator->createOrUpdateSrsCustomer($customer, $event->getContext());
}elseif($event->getWriteResults()[0]->getOperation() == "update"){
if(in_array("lastLogin", array_keys($payload))){
$this->customerCommunicator->checkSrsCustomerForChanges($customer, $event->getContext());
}elseif(in_array("updatedAt", array_keys($payload))){
if(array_key_exists("firstName", $payload) && array_key_exists("lastName", $payload)){
if($payload['firstName'] != $customer->getDefaultBillingAddress()->getFirstName() || $payload['lastName'] != $customer->getDefaultBillingAddress()->getLastName()){
$data = ['id' => $customer->getId(), "defaultBillingAddress" => ["id" => $customer->getDefaultBillingAddress()->getId(), "firstName" => $payload['firstName'], "lastName" => $payload['lastName']]];
$this->customerRepository->upsert([$data], $event->getContext());
return; // This one also triggers the complete flow
}
$this->customerCommunicator->updateCurrentSrsCustomer($customer, $event->getContext());
}
}
}
}
private function retrieveCustomer($customerId, Context $context){
try{
$criteria = new Criteria([$customerId]);
$criteria->addAssociation("defaultBillingAddress.country");
$criteria->addAssociation("defaultShippingAddress.country");
$criteria->addAssociation("salutation");
$criteria->addAssociation("country");
$customer = $this->customerRepository->search($criteria, $context)->first();
} catch (InvalidUuidException $e) {
return false;
}
if(!$customer){
return false;
}
if($customer->getGuest()){
return false;
}
return $customer;
}
}