custom/plugins/IronMatomo/src/Subscriber/MatomoSettingsSubscriber.php line 84

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace IronMatomo\Subscriber;
  3. use IronMatomo\Matomo\MatomoDataService;
  4. use Shopware\Core\Checkout\Cart\LineItem\LineItem;
  5. use Shopware\Core\Checkout\Cart\LineItem\LineItemCollection;
  6. use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemCollection;
  7. use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
  8. use Shopware\Core\Content\Category\Exception\CategoryNotFoundException;
  9. use Shopware\Core\Content\Category\Service\CategoryBreadcrumbBuilder;
  10. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  13. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  14. use Shopware\Storefront\Event\StorefrontRenderEvent;
  15. use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
  16. use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
  17. use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
  18. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  19. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  20. /**
  21.  * Class MatomoSettingsSubscriber
  22.  *
  23.  * @package IronMatomo\Subscriber
  24.  */
  25. class MatomoSettingsSubscriber implements EventSubscriberInterface
  26. {
  27.     const MATOMO_DATA_EXTENSION_ID 'ironMatomoData';
  28.     const MATOMO_DATA_RUNTIME_ID 'ironMatomoExt';
  29.     /**
  30.      * @var MatomoDataService
  31.      */
  32.     private MatomoDataService $matomoDataService;
  33.     /**
  34.      * @var EntityRepositoryInterface
  35.      */
  36.     private EntityRepositoryInterface $productRepository;
  37.     /**
  38.      * @var CategoryBreadcrumbBuilder
  39.      */
  40.     private CategoryBreadcrumbBuilder $breadcrumbBuilder;
  41.     /**
  42.      * MatomoSettingsSubscriber constructor.
  43.      *
  44.      * @param MatomoDataService $matomoDataService
  45.      * @param EntityRepositoryInterface $productRepository
  46.      * @param CategoryBreadcrumbBuilder $breadcrumbBuilder
  47.      */
  48.     public function __construct(
  49.         MatomoDataService $matomoDataService,
  50.         EntityRepositoryInterface $productRepository,
  51.         CategoryBreadcrumbBuilder $breadcrumbBuilder
  52.     )
  53.     {
  54.         $this->matomoDataService $matomoDataService;
  55.         $this->productRepository $productRepository;
  56.         $this->breadcrumbBuilder $breadcrumbBuilder;
  57.     }
  58.     /*
  59.      * @inherit
  60.      */
  61.     public static function getSubscribedEvents(): array
  62.     {
  63.         return [
  64.             StorefrontRenderEvent::class => 'onStorefrontRender',
  65.             ProductPageLoadedEvent::class => 'onProductPageLoaded',
  66.             CheckoutCartPageLoadedEvent::class => 'onCheckoutCartPageLoaded',
  67.             CheckoutConfirmPageLoadedEvent::class => 'onCheckoutConfirmPageLoaded',
  68.             CheckoutFinishPageLoadedEvent::class => 'onCheckoutFinishPageLoaded',
  69.         ];
  70.     }
  71.     /**
  72.      * @param StorefrontRenderEvent $event
  73.      * @throws \Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException
  74.      */
  75.     public function onStorefrontRender(StorefrontRenderEvent $event)
  76.     {
  77.         if ($event->getRequest()->isXmlHttpRequest()) {
  78.             return;
  79.         }
  80.         $parameters $event->getParameters();
  81.         if (isset($parameters['page'])) {
  82.             $matomoData $this->matomoDataService->getMatomoData($event->getSalesChannelContext());
  83.             $page $parameters['page'];
  84.             // Absicherung, weil jemand das Objekt $page zerschießt und ein array daraus macht.
  85.             // https://account.shopware.com/producer/support/164186
  86.             if (is_array($page)) {
  87.                 $page['extension'][self::MATOMO_DATA_EXTENSION_ID] = $matomoData;
  88.                 return;
  89.             }
  90.             $page->addExtensions([self::MATOMO_DATA_EXTENSION_ID => $matomoData]);
  91.         }
  92.     }
  93.     /**
  94.      * @param ProductPageLoadedEvent $event
  95.      * @return void
  96.      */
  97.     public function onProductPageLoaded(ProductPageLoadedEvent $event)
  98.     {
  99.         $salesChannelContext $event->getSalesChannelContext();
  100.         $categoryEntity $this->breadcrumbBuilder->getProductSeoCategory($event->getPage()->getProduct(), $salesChannelContext);
  101.         $event->getPage()->addArrayExtension(self::MATOMO_DATA_RUNTIME_ID, [
  102.             'seoCategory' => $categoryEntity $categoryEntity->getTranslation('name') : null,
  103.         ]);
  104.     }
  105.     /**
  106.      * @param CheckoutCartPageLoadedEvent $event
  107.      * @return void
  108.      */
  109.     public function onCheckoutCartPageLoaded(CheckoutCartPageLoadedEvent $event): void
  110.     {
  111.         $lineItems $event->getPage()->getCart()->getLineItems();
  112.         $cardData $this->getDataForEachLineItem($lineItems$event->getSalesChannelContext());
  113.         $event->getPage()->addArrayExtension(self::MATOMO_DATA_RUNTIME_ID, [
  114.             'seoCategory' => $cardData,
  115.         ]);
  116.     }
  117.     /**
  118.      * @param CheckoutConfirmPageLoadedEvent $event
  119.      * @return void
  120.      */
  121.     public function onCheckoutConfirmPageLoaded(CheckoutConfirmPageLoadedEvent $event): void
  122.     {
  123.         $lineItems $event->getPage()->getCart()->getLineItems();
  124.         $cardData $this->getDataForEachLineItem($lineItems$event->getSalesChannelContext());
  125.         $event->getPage()->addArrayExtension(self::MATOMO_DATA_RUNTIME_ID, [
  126.             'seoCategory' => $cardData,
  127.         ]);
  128.     }
  129.     /**
  130.      * @param CheckoutFinishPageLoadedEvent $event
  131.      * @return void
  132.      */
  133.     public function onCheckoutFinishPageLoaded(CheckoutFinishPageLoadedEvent $event): void
  134.     {
  135.         $lineItems $event->getPage()->getOrder()->getLineItems();
  136.         $cardData $this->getDataForEachLineItem($lineItems$event->getSalesChannelContext());
  137.         $event->getPage()->addArrayExtension(self::MATOMO_DATA_RUNTIME_ID, [
  138.             'seoCategory' => $cardData,
  139.         ]);
  140.     }
  141.     /**
  142.      * @param OrderLineItemCollection|LineItemCollection|null $lineItems
  143.      * @param SalesChannelContext $salesChannelContext
  144.      * @return array
  145.      */
  146.     private function getDataForEachLineItem($lineItemsSalesChannelContext $salesChannelContext): array
  147.     {
  148.         if ($lineItems === null) {
  149.             return [];
  150.         }
  151.         $cardData = [];
  152.         /** @var OrderLineItemEntity|LineItem $item */
  153.         foreach ($lineItems as $item)
  154.         {
  155.             $payload $item->getPayload();
  156.             try {
  157.                 if (!isset($payload['productNumber'])) {
  158.                     continue;
  159.                 }
  160.                 $productNumber $payload['productNumber'];
  161.                 $cardData$productNumber ] =  $this->findCategoryNameByProductNumber($productNumber$salesChannelContext);
  162.             } catch (CategoryNotFoundException $exception) {
  163.                 // Handle category not found exception
  164.             }
  165.         }
  166.         return $cardData;
  167.     }
  168.     /**
  169.      * @param string $productNumber
  170.      * @param SalesChannelContext $salesChannelContext
  171.      * @return string|null
  172.      */
  173.     private function findCategoryNameByProductNumber(string $productNumberSalesChannelContext $salesChannelContext): ?string
  174.     {
  175.         $context $salesChannelContext->getContext();
  176.         try
  177.         {
  178.             $product $this->productRepository->search(
  179.                 (new Criteria())
  180.                     ->addFilter(new EqualsFilter('productNumber'$productNumber)),
  181.                 $context
  182.             )->first();
  183.             $category null;
  184.             if ($product) {
  185.                 $category $this->breadcrumbBuilder->getProductSeoCategory($product$salesChannelContext);
  186.             }
  187.         } catch (\Exception $exception) {
  188.             $category null;
  189.         }
  190.         return $category $category->getTranslation('name') : null;
  191.     }
  192. }