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

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.     const MATOMO_DATA_EXTENSION_ID 'ironMatomoData';
  27.     const MATOMO_DATA_RUNTIME_ID 'ironMatomoExt';
  28.     /**
  29.      * @var MatomoDataService
  30.      */
  31.     private MatomoDataService $matomoDataService;
  32.     /**
  33.      * @var EntityRepositoryInterface
  34.      */
  35.     private EntityRepositoryInterface $productRepository;
  36.     /**
  37.      * @var CategoryBreadcrumbBuilder
  38.      */
  39.     private CategoryBreadcrumbBuilder $breadcrumbBuilder;
  40.     /**
  41.      * MatomoSettingsSubscriber constructor.
  42.      *
  43.      * @param MatomoDataService $matomoDataService
  44.      * @param EntityRepositoryInterface $productRepository
  45.      * @param CategoryBreadcrumbBuilder $breadcrumbBuilder
  46.      */
  47.     public function __construct(
  48.         MatomoDataService $matomoDataService,
  49.         EntityRepositoryInterface $productRepository,
  50.         CategoryBreadcrumbBuilder $breadcrumbBuilder,
  51.     ) {
  52.         $this->matomoDataService $matomoDataService;
  53.         $this->productRepository $productRepository;
  54.         $this->breadcrumbBuilder $breadcrumbBuilder;
  55.     }
  56.     /*
  57.      * @inherit
  58.      */
  59.     public static function getSubscribedEvents(): array {
  60.         return [
  61.             StorefrontRenderEvent::class => ['onStorefrontRender'100],
  62.             ProductPageLoadedEvent::class => ['onProductPageLoaded'100],
  63.             CheckoutCartPageLoadedEvent::class => ['onCheckoutCartPageLoaded'100],
  64.             CheckoutConfirmPageLoadedEvent::class => ['onCheckoutConfirmPageLoaded'100],
  65.             CheckoutFinishPageLoadedEvent::class => ['onCheckoutFinishPageLoaded'100],
  66.         ];
  67.     }
  68.     /**
  69.      * @param StorefrontRenderEvent $event
  70.      * @throws \Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException
  71.      */
  72.     public function onStorefrontRender(StorefrontRenderEvent $event) {
  73.         if ($event->getRequest()->isXmlHttpRequest()) {
  74.             return;
  75.         }
  76.         $parameters $event->getParameters();
  77.         if (isset($parameters['page'])) {
  78.             $matomoData $this->matomoDataService->getMatomoData($event->getSalesChannelContext());
  79.             $page $parameters['page'];
  80.             // Absicherung, weil jemand das Objekt $page zerschießt und ein array daraus macht.
  81.             // https://account.shopware.com/producer/support/164186
  82.             if (is_array($page)) {
  83.                 $page['extension'][self::MATOMO_DATA_EXTENSION_ID] = $matomoData;
  84.                 return;
  85.             }
  86.             $page->addExtensions([self::MATOMO_DATA_EXTENSION_ID => $matomoData]);
  87.         }
  88.     }
  89.     /**
  90.      * @param ProductPageLoadedEvent $event
  91.      * @return void
  92.      */
  93.     public function onProductPageLoaded(ProductPageLoadedEvent $event) {
  94.         $salesChannelContext $event->getSalesChannelContext();
  95.         $categoryEntity $this->breadcrumbBuilder->getProductSeoCategory(
  96.             $event->getPage()->getProduct(),
  97.             $salesChannelContext,
  98.         );
  99.         $event->getPage()->addArrayExtension(self::MATOMO_DATA_RUNTIME_ID, [
  100.             'seoCategory' => $categoryEntity $categoryEntity->getTranslation('name') : null,
  101.         ]);
  102.     }
  103.     /**
  104.      * @param CheckoutCartPageLoadedEvent $event
  105.      * @return void
  106.      */
  107.     public function onCheckoutCartPageLoaded(CheckoutCartPageLoadedEvent $event): void {
  108.         $lineItems $event
  109.             ->getPage()
  110.             ->getCart()
  111.             ->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.         $lineItems $event
  123.             ->getPage()
  124.             ->getCart()
  125.             ->getLineItems();
  126.         $cardData $this->getDataForEachLineItem($lineItems$event->getSalesChannelContext());
  127.         $event->getPage()->addArrayExtension(self::MATOMO_DATA_RUNTIME_ID, [
  128.             'seoCategory' => $cardData,
  129.         ]);
  130.     }
  131.     /**
  132.      * @param CheckoutFinishPageLoadedEvent $event
  133.      * @return void
  134.      */
  135.     public function onCheckoutFinishPageLoaded(CheckoutFinishPageLoadedEvent $event): void {
  136.         $lineItems $event
  137.             ->getPage()
  138.             ->getOrder()
  139.             ->getLineItems();
  140.         $cardData $this->getDataForEachLineItem($lineItems$event->getSalesChannelContext());
  141.         $event->getPage()->addArrayExtension(self::MATOMO_DATA_RUNTIME_ID, [
  142.             'seoCategory' => $cardData,
  143.         ]);
  144.     }
  145.     /**
  146.      * @param OrderLineItemCollection|LineItemCollection|null $lineItems
  147.      * @param SalesChannelContext $salesChannelContext
  148.      * @return array
  149.      */
  150.     private function getDataForEachLineItem($lineItemsSalesChannelContext $salesChannelContext): array {
  151.         if ($lineItems === null) {
  152.             return [];
  153.         }
  154.         $cardData = [];
  155.         /** @var OrderLineItemEntity|LineItem $item */
  156.         foreach ($lineItems as $item) {
  157.             $payload $item->getPayload();
  158.             try {
  159.                 if (!isset($payload['productNumber'])) {
  160.                     continue;
  161.                 }
  162.                 $productNumber $payload['productNumber'];
  163.                 $cardData[$productNumber] = $this->findCategoryNameByProductNumber(
  164.                     $productNumber,
  165.                     $salesChannelContext,
  166.                 );
  167.             } catch (CategoryNotFoundException $exception) {
  168.                 // Handle category not found exception
  169.             }
  170.         }
  171.         return $cardData;
  172.     }
  173.     /**
  174.      * @param string $productNumber
  175.      * @param SalesChannelContext $salesChannelContext
  176.      * @return string|null
  177.      */
  178.     private function findCategoryNameByProductNumber(
  179.         string $productNumber,
  180.         SalesChannelContext $salesChannelContext,
  181.     ): ?string {
  182.         $context $salesChannelContext->getContext();
  183.         try {
  184.             $product $this->productRepository
  185.                 ->search(
  186.                     (new Criteria())->addFilter(new EqualsFilter('productNumber'$productNumber)),
  187.                     $context,
  188.                 )
  189.                 ->first();
  190.             $category null;
  191.             if ($product) {
  192.                 $category $this->breadcrumbBuilder->getProductSeoCategory($product$salesChannelContext);
  193.             }
  194.         } catch (\Exception $exception) {
  195.             $category null;
  196.         }
  197.         return $category $category->getTranslation('name') : null;
  198.     }
  199. }