src/PentagastBundle/Subscriber/VatIdCheckoutSubscriber.php line 40

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. /**
  3.  * dk communications
  4.  * Copyright (c) 2025.
  5.  *
  6.  * All rights reserved.
  7.  *
  8.  */
  9.  
  10. namespace Valantic\Bundle\PentagastBundle\Subscriber;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. use Symfony\Component\HttpKernel\KernelEvents;
  13. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  14. use Symfony\Component\HttpFoundation\RedirectResponse;
  15. use Symfony\Component\HttpFoundation\RequestStack;
  16. use Symfony\Component\Routing\RouterInterface;
  17. use Shopware\Core\PlatformRequest;
  18. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  19. use Shopware\Core\System\SalesChannel\Context\SalesChannelContextService;
  20. use Shopware\Core\System\SalesChannel\Context\SalesChannelContextServiceParameters;
  21. use Valantic\Bundle\PentagastBundle\Service\ShopFeaturesService;
  22. class VatIdCheckoutSubscriber implements EventSubscriberInterface
  23. {
  24.     public function __construct(
  25.         private readonly ShopFeaturesService $shopFeaturesService,
  26.         private readonly RouterInterface $router,
  27.         private readonly RequestStack $requestStack,
  28.         private readonly SalesChannelContextService $scContextService
  29.     ) {}
  30.     public static function getSubscribedEvents(): array
  31.     {
  32.         return [
  33.             KernelEvents::CONTROLLER => ['onController'0],
  34.         ];
  35.     }
  36.     public function onController(ControllerEvent $event): void
  37.     {
  38.         // nur Haupt-Request
  39.         if (method_exists($event'isMainRequest')) {
  40.             if (!$event->isMainRequest()) { return; }
  41.         } elseif (method_exists($event'isMasterRequest') && !$event->isMasterRequest()) {
  42.             return;
  43.         }
  44.         $request $event->getRequest();
  45.         $route   = (string) ($request->attributes->get('_route') ?? '');
  46.         // nur relevante Checkout-Routen
  47.         $guardedRoutes = [
  48.             'frontend.checkout.confirm.page',
  49.             'frontend.checkout.order.place',
  50.         ];
  51.         if (!\in_array($route$guardedRoutestrue)) {
  52.             return;
  53.         }
  54.         // SalesChannelContext aus Request oder via Fallback rekonstruieren
  55.         /** @var SalesChannelContext|null $scContext */
  56.         $scContext $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
  57.         if (!$scContext instanceof SalesChannelContext) {
  58.             $salesChannelId = (string) ($request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID) ?? '');
  59.             $token = (string) ($request->headers->get(PlatformRequest::HEADER_CONTEXT_TOKEN)
  60.                 ?? $request->cookies->get(PlatformRequest::COOKIE_CONTEXT_TOKEN)
  61.                 ?? '');
  62.             if ($salesChannelId && $token) {
  63.                 try {
  64.                     $params   = new SalesChannelContextServiceParameters($salesChannelId$token);
  65.                     $scContext $this->scContextService->get($params);
  66.                 } catch (\Throwable) {
  67.                     return;
  68.                 }
  69.             } else {
  70.                 return;
  71.             }
  72.         }
  73.         // Feature am Verkaufskanal aktiv?
  74.         if (!$this->shopFeaturesService->vatIdRequiredForCheckout($scContext)) {
  75.             return;
  76.         }
  77.         // Kunde & VAT-ID check
  78.         $customer $scContext->getCustomer();
  79.         if (!$customer || $this->shopFeaturesService->customerHasVatId($customer)) {
  80.             return;
  81.         }
  82.         // blockieren & zum Profil leiten
  83.         $this->flash(
  84.             'danger',
  85.             'Für diesen Shop ist die Angabe einer Umsatzsteuer-ID für den Kauf verpflichtend. Bitte ergänzen Sie die Umsatzsteuer-ID in Ihrem Profil.'
  86.         );
  87.         $profileUrl $this->router->generate('frontend.account.profile.page');
  88.         $event->setController(fn () => new RedirectResponse($profileUrl));
  89.     }
  90.     private function flash(string $typestring $message): void
  91.     {
  92.         if ($session $this->requestStack->getSession()) {
  93.             $session->getFlashBag()->add($type$message);
  94.         }
  95.     }
  96. }