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

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. class CheckoutDataSubscriber implements EventSubscriberInterface
  24. {
  25.     private LoggerInterface $logger;
  26.     private SettingsValidationServiceInterface $settingsValidationService;
  27.     private RequestStack $requestStack;
  28.     private TranslatorInterface $translator;
  29.     private EventDispatcherInterface $eventDispatcher;
  30.     private ?iterable $apmCheckoutMethods;
  31.     public function __construct(
  32.         LoggerInterface $logger,
  33.         SettingsValidationServiceInterface $settingsValidationService,
  34.         RequestStack $requestStack,
  35.         TranslatorInterface $translator,
  36.         EventDispatcherInterface $eventDispatcher,
  37.         ?iterable $apmCheckoutMethods null
  38.     ) {
  39.         $this->logger $logger;
  40.         $this->settingsValidationService $settingsValidationService;
  41.         $this->requestStack $requestStack;
  42.         $this->translator $translator;
  43.         $this->eventDispatcher $eventDispatcher;
  44.         $this->apmCheckoutMethods $apmCheckoutMethods;
  45.         if ($this->apmCheckoutMethods !== null) {
  46.             if (!\is_array($this->apmCheckoutMethods)) {
  47.                 $this->apmCheckoutMethods = [...$this->apmCheckoutMethods];
  48.             }
  49.         }
  50.     }
  51.     public static function getSubscribedEvents(): array
  52.     {
  53.         return [
  54.             AccountEditOrderPageLoadedEvent::class => 'onAccountOrderEditLoaded',
  55.             CheckoutConfirmPageLoadedEvent::class => 'onCheckoutConfirmLoaded',
  56.         ];
  57.     }
  58.     public function onAccountOrderEditLoaded(AccountEditOrderPageLoadedEvent $event): void
  59.     {
  60.         if ($this->apmCheckoutMethods === null) {
  61.             return;
  62.         }
  63.         foreach ($this->apmCheckoutMethods as $checkoutMethod) {
  64.             if (!$this->checkSettings($event->getSalesChannelContext(), $checkoutMethod->getHandler())) {
  65.                 continue;
  66.             }
  67.             $this->addExtension($checkoutMethod$eventnull$event->getPage()->getOrder());
  68.         }
  69.     }
  70.     public function onCheckoutConfirmLoaded(CheckoutConfirmPageLoadedEvent $event): void
  71.     {
  72.         if ($this->apmCheckoutMethods === null || $event->getPage()->getCart()->getErrors()->blockOrder()) {
  73.             return;
  74.         }
  75.         foreach ($this->apmCheckoutMethods as $checkoutMethod) {
  76.             if (!$this->checkSettings($event->getSalesChannelContext(), $checkoutMethod->getHandler())) {
  77.                 continue;
  78.             }
  79.             $this->addExtension($checkoutMethod$event$event->getPage()->getCart());
  80.         }
  81.     }
  82.     /**
  83.      * @param class-string $handler
  84.      */
  85.     private function checkSettings(SalesChannelContext $salesChannelContextstring $handler): bool
  86.     {
  87.         if ($salesChannelContext->getPaymentMethod()->getHandlerIdentifier() !== $handler) {
  88.             return false;
  89.         }
  90.         try {
  91.             $this->settingsValidationService->validate($salesChannelContext->getSalesChannelId());
  92.         } catch (PayPalSettingsInvalidException $e) {
  93.             return false;
  94.         }
  95.         return true;
  96.     }
  97.     /**
  98.      * @param CheckoutConfirmPageLoadedEvent|AccountEditOrderPageLoadedEvent $event
  99.      */
  100.     private function addExtension(CheckoutDataMethodInterface $methodDataPageLoadedEvent $event, ?Cart $cart null, ?OrderEntity $order null): void
  101.     {
  102.         $this->logger->debug('Adding data');
  103.         $checkoutData $methodData->getCheckoutDataService()->buildCheckoutData($event->getSalesChannelContext(), $cart$order);
  104.         if (!$checkoutData) {
  105.             return;
  106.         }
  107.         $checkoutData->setPreventErrorReload($this->isErrorReload());
  108.         $page $event->getPage();
  109.         $page->addExtension($methodData->getCheckoutTemplateExtensionId(), $checkoutData);
  110.         $this->eventDispatcher->dispatch(new PayPalPageExtensionAddedEvent($page$methodData$checkoutData));
  111.         $this->logger->debug('Added data');
  112.     }
  113.     /**
  114.      * Checks if a PayPal error was added via Swag\PayPal\Checkout\SalesChannel\ErrorRoute::addErrorMessage
  115.      * and sets the preventErrorReload property of the $checkoutData accordingly.
  116.      */
  117.     private function isErrorReload(): bool
  118.     {
  119.         $request $this->requestStack->getCurrentRequest();
  120.         if ($request !== null && $request->query->has(AbstractCheckoutDataService::PAYPAL_ERROR)) {
  121.             return true;
  122.         }
  123.         $session $this->requestStack->getSession();
  124.         if (!\method_exists($session'getFlashBag')) {
  125.             return false;
  126.         }
  127.         $flashes $session->getFlashBag()->peekAll();
  128.         $possibleMessages = [
  129.             $this->translator->trans('paypal.general.paymentError'),
  130.         ];
  131.         foreach ($flashes as $val) {
  132.             if (\is_array($val) && \array_intersect($val$possibleMessages)) {
  133.                 return true;
  134.             }
  135.             if (\is_string($val) && \in_array($val$possibleMessagestrue)) {
  136.                 return true;
  137.             }
  138.         }
  139.         return false;
  140.     }
  141. }