<?php declare(strict_types=1);
namespace Wexo\Checkout\Subscriber;
use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
use Shopware\Core\Checkout\Order\OrderEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\DefinitionInstanceRegistry;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
use Shopware\Core\System\CustomField\CustomFieldEntity;
use Shopware\Core\System\CustomField\CustomFieldService;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\InputBag;
use Symfony\Component\HttpFoundation\RequestStack;
use Wexo\Checkout\Core\Checkout\Cart\SalesChannel\CartOrderRouteDecorator;
use Wexo\Checkout\Helper\Helper;
use Wexo\Checkout\Struct\CheckoutOrderData;
/**
* Class OrderSubscriber
* @package Wexo\Checkout\Subscriber
*/
class OrderSubscriber implements EventSubscriberInterface
{
/**
* @var Helper
*/
protected $helper;
/**
* @var EntityRepositoryInterface
*/
protected $orderRepository;
/**
* @var CustomFieldService
*/
protected $customFieldService;
/**
* @var DefinitionInstanceRegistry
*/
protected $definitionRegistry;
/**
* @var RequestStack
*/
protected $requestStack;
/**
* OrderSubscriber constructor.
* @param Helper $helper
* @param EntityRepositoryInterface $orderRepository
* @param CustomFieldService $customFieldService
* @param DefinitionInstanceRegistry $definitionRegistry
* @param RequestStack $requestStack
*/
public function __construct(
Helper $helper,
EntityRepositoryInterface $orderRepository,
CustomFieldService $customFieldService,
DefinitionInstanceRegistry $definitionRegistry,
RequestStack $requestStack
) {
$this->helper = $helper;
$this->orderRepository = $orderRepository;
$this->customFieldService = $customFieldService;
$this->definitionRegistry = $definitionRegistry;
$this->requestStack = $requestStack;
}
/**
* @return string[]
*/
public static function getSubscribedEvents(): array
{
return [
CheckoutOrderPlacedEvent::class => [
['onOrderPlaced', 100]
]
];
}
/**
* @param CheckoutOrderPlacedEvent $event
*/
public function onOrderPlaced(CheckoutOrderPlacedEvent $event)
{
$request = $this->requestStack->getCurrentRequest();
if ($request && $inputBag = $request->request) {
$this->addCustomFields(
$inputBag->get('customFields', []),
$event->getOrder(),
$event->getContext()
);
}
}
/**
* @param array $customFields
* @param OrderEntity $order
* @param Context $context
*/
private function addCustomFields(
array $customFields,
OrderEntity $order,
Context $context
): void {
if (!$customFields || empty($customFields)) {
return;
}
$customFields = array_merge($order->getCustomFields() ?? [], $customFields);
$exceptions = [];
// Decode all customField values
foreach ($customFields as $key => &$value) {
$customField = $this->customFieldService->getCustomField($key);
if (!$customField) {
continue;
}
try {
$customField->compile($this->definitionRegistry);
// Decode based on shopware type
$value = $customField->getSerializer()->decode($customField, $value);
} catch (\Exception $e) {
$exceptions[] = $e;
unset($customFields[$key]);
}
}
foreach ($exceptions as $exception) {
$this->helper->error($exception->getMessage(), $exception);
}
try {
$order->setCustomFields($customFields);
$this->orderRepository->update([
[
'id' => $order->getId(),
'customFields' => $customFields
]
], $context);
} catch (\Exception $e) {
// Custom fields could not be saved
$this->helper->error($e->getMessage(), $e);
}
}
}