<?php
declare(strict_types=1);
namespace Uandi\EFB\Storefront\Subscriber;
use Exception;
use Psr\Log\LoggerInterface;
use Shopware\Core\Framework\Context;
use Shopware\Core\Checkout\Order\OrderEvents;
use Symfony\Component\HttpFoundation\RequestStack;
use Shopware\Core\Checkout\Cart\AbstractCartPersister;
use Uandi\EFB\Storefront\Struct\CartPreferenceExtension;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
class OrderSubscriber implements EventSubscriberInterface
{
private EntityRepositoryInterface $orderRepository;
private RequestStack $requestStack;
private AbstractCartPersister $cartPersister;
private LoggerInterface $logger;
private EntityRepositoryInterface $customerRepository;
public function __construct(
EntityRepositoryInterface $orderRepository,
RequestStack $requestStack,
AbstractCartPersister $cartPersister,
LoggerInterface $logger,
EntityRepositoryInterface $customerRepository
) {
$this->orderRepository = $orderRepository;
$this->requestStack = $requestStack;
$this->cartPersister = $cartPersister;
$this->logger = $logger;
$this->customerRepository = $customerRepository;
}
public static function getSubscribedEvents(): array
{
return [
OrderEvents::ORDER_WRITTEN_EVENT => 'onOrderWritten'
];
}
public function onOrderWritten(EntityWrittenEvent $event)
{
$request = $this->requestStack->getCurrentRequest();
if (null === $request) return;
/** @var SalesChannelContext $salesChannelContext */
$salesChannelContext = $request->get('sw-sales-channel-context') ?? null;
if (null === $salesChannelContext) {
$this->logger->error('Not possible to save preferences into order. salesChannelContext not found.');
return;
}
if ($salesChannelContext->getCustomerId()) {
$this->tagCustomer($salesChannelContext->getCustomerId(), $event->getContext());
}
$av_contact_person = $request->get('av_contact_person') ? $request->get('av_contact_person') : null;
$av_phone_number = $request->get('av_phone_number') ? $request->get('av_phone_number') : null;
$av_active = $request->get('av_active') ? 'true' : 'false';
$context = $event->getContext();
foreach ($event->getWriteResults() as $writeResult) {
if ($writeResult->getExistence() !== null && $writeResult->getExistence()->exists()) continue;
if ($writeResult->getOperation() !== 'insert') continue;
$payload = $writeResult->getPayload();
if (empty($payload)) continue;
$customFields = !empty($payload['customFields']) ? $payload['customFields'] : [];
if (!empty($customFields) && !empty($customFields['preferences'])) continue;
try {
$customFields['preferences'] = $this->getCartPreferences($salesChannelContext->getToken() ?? '', $salesChannelContext);
$customFields['av_contact_person'] = $av_contact_person;
$customFields['av_phone_number'] = $av_phone_number;
$customFields['av_active'] = $av_active;
$data = [
[
'id' => $payload['id'],
'customFields' => $customFields
]
];
$this->orderRepository->update($data, $context);
} catch (Exception $exception) {
$this->logger->error('Error while processing saving preferences into order: ' . $exception->getMessage());
}
}
}
private function getCartPreferences(string $cartToken, SalesChannelContext $salesChannelContext): array
{
$cart = $this->cartPersister->load($cartToken, $salesChannelContext);
$cartPreferences = $cart->getExtension(CartPreferenceExtension::NAME);
return $cartPreferences->getCartPreferences() ?? [];
}
private function tagCustomer(string $customerId, Context $context): void
{
$this->customerRepository->upsert([[
'id' => $customerId,
'customFields' => ['emz_customer_has_ordered_in_shop' => true]
]], $context);
}
}