custom/plugins/SwagPayPal/src/Storefront/Data/CheckoutDataSubscriber.php line 88

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. /*
  3.  * (c) shopware AG <info@shopware.com>
  4.  * For the full copyright and license information, please view the LICENSE
  5.  * file that was distributed with this source code.
  6.  */
  7. namespace Swag\PayPal\Storefront\Data;
  8. use Psr\Log\LoggerInterface;
  9. use Shopware\Core\Checkout\Cart\Cart;
  10. use Shopware\Core\Checkout\Order\OrderEntity;
  11. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  12. use Shopware\Storefront\Page\Account\Order\AccountEditOrderPageLoadedEvent;
  13. use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
  14. use Shopware\Storefront\Page\PageLoadedEvent;
  15. use Swag\PayPal\Setting\Exception\PayPalSettingsInvalidException;
  16. use Swag\PayPal\Setting\Service\SettingsValidationServiceInterface;
  17. use Swag\PayPal\Storefront\Data\Event\PayPalPageExtensionAddedEvent;
  18. use Swag\PayPal\Storefront\Data\Service\AbstractCheckoutDataService;
  19. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  20. use Symfony\Component\HttpFoundation\RequestStack;
  21. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  22. use Symfony\Contracts\Translation\TranslatorInterface;
  23. /**
  24.  * @internal
  25.  */
  26. class CheckoutDataSubscriber implements EventSubscriberInterface
  27. {
  28.     private LoggerInterface $logger;
  29.     private SettingsValidationServiceInterface $settingsValidationService;
  30.     private RequestStack $requestStack;
  31.     private TranslatorInterface $translator;
  32.     private EventDispatcherInterface $eventDispatcher;
  33.     private ?iterable $apmCheckoutMethods;
  34.     public function __construct(
  35.         LoggerInterface $logger,
  36.         SettingsValidationServiceInterface $settingsValidationService,
  37.         RequestStack $requestStack,
  38.         TranslatorInterface $translator,
  39.         EventDispatcherInterface $eventDispatcher,
  40.         ?iterable $apmCheckoutMethods null
  41.     ) {
  42.         $this->logger $logger;
  43.         $this->settingsValidationService $settingsValidationService;
  44.         $this->requestStack $requestStack;
  45.         $this->translator $translator;
  46.         $this->eventDispatcher $eventDispatcher;
  47.         $this->apmCheckoutMethods $apmCheckoutMethods;
  48.         if ($this->apmCheckoutMethods !== null) {
  49.             if (!\is_array($this->apmCheckoutMethods)) {
  50.                 $this->apmCheckoutMethods = [...$this->apmCheckoutMethods];
  51.             }
  52.         }
  53.     }
  54.     public static function getSubscribedEvents(): array
  55.     {
  56.         return [
  57.             AccountEditOrderPageLoadedEvent::class => 'onAccountOrderEditLoaded',
  58.             CheckoutConfirmPageLoadedEvent::class => 'onCheckoutConfirmLoaded',
  59.         ];
  60.     }
  61.     public function onAccountOrderEditLoaded(AccountEditOrderPageLoadedEvent $event): void
  62.     {
  63.         if ($this->apmCheckoutMethods === null) {
  64.             return;
  65.         }
  66.         foreach ($this->apmCheckoutMethods as $checkoutMethod) {
  67.             if (!$this->checkSettings($event->getSalesChannelContext(), $checkoutMethod->getHandler())) {
  68.                 continue;
  69.             }
  70.             $this->addExtension($checkoutMethod$eventnull$event->getPage()->getOrder());
  71.         }
  72.     }
  73.     public function onCheckoutConfirmLoaded(CheckoutConfirmPageLoadedEvent $event): void
  74.     {
  75.         if ($this->apmCheckoutMethods === null || $event->getPage()->getCart()->getErrors()->blockOrder()) {
  76.             return;
  77.         }
  78.         foreach ($this->apmCheckoutMethods as $checkoutMethod) {
  79.             if (!$this->checkSettings($event->getSalesChannelContext(), $checkoutMethod->getHandler())) {
  80.                 continue;
  81.             }
  82.             $this->addExtension($checkoutMethod$event$event->getPage()->getCart());
  83.         }
  84.     }
  85.     /**
  86.      * @param class-string $handler
  87.      */
  88.     private function checkSettings(SalesChannelContext $salesChannelContextstring $handler): bool
  89.     {
  90.         if ($salesChannelContext->getPaymentMethod()->getHandlerIdentifier() !== $handler) {
  91.             return false;
  92.         }
  93.         try {
  94.             $this->settingsValidationService->validate($salesChannelContext->getSalesChannelId());
  95.         } catch (PayPalSettingsInvalidException $e) {
  96.             return false;
  97.         }
  98.         return true;
  99.     }
  100.     /**
  101.      * @param CheckoutConfirmPageLoadedEvent|AccountEditOrderPageLoadedEvent $event
  102.      */
  103.     private function addExtension(CheckoutDataMethodInterface $methodDataPageLoadedEvent $event, ?Cart $cart null, ?OrderEntity $order null): void
  104.     {
  105.         $this->logger->debug('Adding data');
  106.         $checkoutData $methodData->getCheckoutDataService()->buildCheckoutData($event->getSalesChannelContext(), $cart$order);
  107.         if (!$checkoutData) {
  108.             return;
  109.         }
  110.         $checkoutData->setPreventErrorReload($this->isErrorReload());
  111.         $page $event->getPage();
  112.         $page->addExtension($methodData->getCheckoutTemplateExtensionId(), $checkoutData);
  113.         $this->eventDispatcher->dispatch(new PayPalPageExtensionAddedEvent($page$methodData$checkoutData));
  114.         $this->logger->debug('Added data');
  115.     }
  116.     /**
  117.      * Checks if a PayPal error was added via Swag\PayPal\Checkout\SalesChannel\ErrorRoute::addErrorMessage
  118.      * and sets the preventErrorReload property of the $checkoutData accordingly.
  119.      */
  120.     private function isErrorReload(): bool
  121.     {
  122.         $request $this->requestStack->getCurrentRequest();
  123.         if ($request !== null && $request->query->has(AbstractCheckoutDataService::PAYPAL_ERROR)) {
  124.             return true;
  125.         }
  126.         $session $this->requestStack->getSession();
  127.         if (!\method_exists($session'getFlashBag')) {
  128.             return false;
  129.         }
  130.         $flashes $session->getFlashBag()->peekAll();
  131.         $possibleMessages = [
  132.             $this->translator->trans('paypal.general.paymentError'),
  133.         ];
  134.         foreach ($flashes as $val) {
  135.             if (\is_array($val) && \array_intersect($val$possibleMessages)) {
  136.                 return true;
  137.             }
  138.             if (\is_string($val) && \in_array($val$possibleMessagestrue)) {
  139.                 return true;
  140.             }
  141.         }
  142.         return false;
  143.     }
  144. }