custom/plugins/KlarnaPayment/src/Components/EventListener/OrderChangeEventListener.php line 67

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace KlarnaPayment\Components\EventListener;
  4. use KlarnaPayment\Components\Helper\OrderFetcherInterface;
  5. use KlarnaPayment\Components\Helper\OrderValidator\OrderValidatorInterface;
  6. use KlarnaPayment\Components\Helper\OrderValidator\OrderValidator;
  7. use KlarnaPayment\Core\Framework\ContextScope;
  8. use Shopware\Core\Checkout\Order\Aggregate\OrderAddress\OrderAddressDefinition;
  9. use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemDefinition;
  10. use Shopware\Core\Checkout\Order\OrderDefinition;
  11. use Shopware\Core\Checkout\Order\OrderEntity;
  12. use Shopware\Core\Defaults;
  13. use Shopware\Core\Framework\Uuid\Uuid;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Write\Validation\PreWriteValidationEvent;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\UpdateCommand;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Write\Validation\PostWriteValidationEvent;
  17. use Shopware\Core\Framework\Validation\WriteConstraintViolationException;
  18. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  19. use Symfony\Component\Validator\ConstraintViolation;
  20. use Symfony\Component\Validator\ConstraintViolationList;
  21. use Symfony\Contracts\Translation\TranslatorInterface;
  22. use Symfony\Component\HttpFoundation\RequestStack;
  23. class OrderChangeEventListener implements EventSubscriberInterface
  24. {
  25.     /** @var OrderFetcherInterface */
  26.     private $orderFetcher;
  27.     /** @var TranslatorInterface */
  28.     private $translator;
  29.     /** @var OrderValidatorInterface */
  30.     private $orderValidator;
  31.     /** @var string */
  32.     private $currentLocale;
  33.     /** @var RequestStack */
  34.     private $requestStack;
  35.     private $previousOrder null
  36.     public function __construct(
  37.         OrderFetcherInterface $orderFetcher,
  38.         TranslatorInterface $translator,
  39.         OrderValidatorInterface $orderValidator,
  40.         RequestStack $requestStack
  41.     ) {
  42.         $this->orderFetcher   $orderFetcher;
  43.         $this->translator     $translator;
  44.         $this->orderValidator $orderValidator;
  45.         $this->requestStack   $requestStack;
  46.     }
  47.     public static function getSubscribedEvents(): array
  48.     {
  49.         return [
  50.             PostWriteValidationEvent::class => 'validateKlarnaOrder',
  51.             PreWriteValidationEvent::class => 'savePreviousOrderData'
  52.         ];
  53.     }
  54.     public function savePreviousOrderData(PreWriteValidationEvent $event): void
  55.     {
  56.         $previousOrder $this->getOrderFromWriteCommands($event);
  57.         if ($previousOrder === null || !$this->orderValidator->isKlarnaOrder($previousOrder)) {
  58.             return;
  59.         }
  60.         $this->previousOrder $previousOrder;
  61.     }
  62.     /**
  63.      * @see \KlarnaPayment\Components\Controller\Administration\OrderUpdateController::update Change accordingly to keep functionality synchronized
  64.      */
  65.     public function validateKlarnaOrder(PostWriteValidationEvent $event): void
  66.     {
  67.         if ($event->getContext()->getScope() === ContextScope::INTERNAL_SCOPE) {
  68.             // only check user generated changes
  69.             return;
  70.         }
  71.         if ($event->getContext()->getVersionId() !== Defaults::LIVE_VERSION) {
  72.             // No live data change, just draft versions
  73.             return;
  74.         }
  75.         $order $this->getOrderFromWriteCommands($event);
  76.         if ($order === null || !$this->orderValidator->isKlarnaOrder($order)) {
  77.             return;
  78.         }
  79.         $this->setCurrentLocale($event);
  80.         $this->validateOrderAddress($order$event);
  81.         $this->validateLineItems($order$event);
  82.     }
  83.     private function setCurrentLocale(PostWriteValidationEvent $event): void
  84.     {
  85.         $languages           $event->getWriteContext()->getLanguages();
  86.         $this->currentLocale $languages[$event->getContext()->getLanguageId()]['code'] ?? 'en-GB';
  87.     }
  88.     private function validateLineItems(OrderEntity $orderEntityPostWriteValidationEvent $event): void
  89.     {
  90.         if ($this->orderValidator->validateAndInitLineItemsHash($orderEntity$event->getContext())) {
  91.             return;
  92.         }
  93.         $violation = new ConstraintViolation(
  94.             $this->translator->trans('KlarnaPayment.errorMessages.lineItemChangeDeclined', [], null$this->currentLocale),
  95.             '',
  96.             [],
  97.             '',
  98.             '',
  99.             ''
  100.         );
  101.         $violations = new ConstraintViolationList([$violation]);
  102.         $event->getExceptions()->add(new WriteConstraintViolationException($violations));
  103.     }
  104.     private function validateOrderAddress(OrderEntity $orderEntityPostWriteValidationEvent $event): void
  105.     {
  106.         $validationErrors = [];
  107.         if ($this->orderValidator->validateAndInitOrderAddressHash($orderEntity$this->previousOrder$event->getContext(), $validationErrors)) {
  108.             $this->previousOrder null;
  109.             return;
  110.         }
  111.         $this->previousOrder null;
  112.         $message '';
  113.         $params = [];
  114.         if($validationErrors !== []){
  115.             $message json_encode($validationErrors['message']);
  116.             $params $validationErrors['params'];
  117.         }
  118.         $violation = new ConstraintViolation(
  119.             $this->translator->trans('KlarnaPayment.errorMessages.addressChangeDeclined', [], null$this->currentLocale),
  120.             $message,
  121.             $params,
  122.             '',
  123.             '',
  124.             ''
  125.         );
  126.         $violations = new ConstraintViolationList([$violation]);
  127.         $event->getExceptions()->add(new WriteConstraintViolationException($violations));
  128.     }
  129.     private function getOrderFromWriteCommands($event): ?OrderEntity
  130.     {
  131.         foreach ($event->getCommands() as $command) {
  132.             if (!($command instanceof UpdateCommand)) {
  133.                 continue;
  134.             }
  135.             $primaryKeys $command->getPrimaryKey();
  136.             if (!array_key_exists('id'$primaryKeys) || empty($primaryKeys['id'])) {
  137.                 continue;
  138.             }
  139.             if ($command->getDefinition()->getClass() === OrderAddressDefinition::class) {
  140.                 return $this->orderFetcher->getOrderFromOrderAddress($primaryKeys['id'], $event->getContext());
  141.             }
  142.             if ($command->getDefinition()->getClass() === OrderLineItemDefinition::class) {
  143.                 return $this->orderFetcher->getOrderFromOrderLineItem($primaryKeys['id'], $event->getContext());
  144.             }
  145.             if ($command->getDefinition()->getClass() === OrderDefinition::class) {
  146.                 return $this->orderFetcher->getOrderFromOrder($primaryKeys['id'], $event->getContext());
  147.             }
  148.         }
  149.         return null;
  150.     }
  151. }