custom/plugins/LoyxxSW6SeoFaqManager/src/Subscribers/StorefrontPageLoadedEvent.php line 49

Open in your IDE?
  1. <?php
  2. namespace LoyxxSW6SeoFaqManager\Subscribers;
  3. use LoyxxSW6SeoFaqManager\Core\Content\Cms\Struct\CategorySeoFaqStruct;
  4. use LoyxxSW6SeoFaqManager\Core\Content\FaqCategory\FaqCategoryCollection;
  5. use LoyxxSW6SeoFaqManager\Core\Content\FaqCategory\FaqCategoryEntity;
  6. use LoyxxSW6SeoFaqManager\Core\Content\FaqCategory\Item\FaqCategoryItemEntity;
  7. use LoyxxSW6SeoFaqManager\Core\Content\FaqProduct\FaqProductCollection;
  8. use LoyxxSW6SeoFaqManager\Core\Content\FaqProduct\FaqProductEntity;
  9. use LoyxxSW6SeoFaqManager\Core\Content\FaqProduct\Item\FaqProductItemEntity;
  10. use LoyxxSW6SeoFaqManager\Core\Content\FaqSet\FaqSetCollection;
  11. use LoyxxSW6SeoFaqManager\Core\Content\FaqSet\FaqSetEntity;
  12. use LoyxxSW6SeoFaqManager\Core\Content\FaqSet\FaqSetItem\FaqSetItemEntity;
  13. use LoyxxSW6SeoFaqManager\Core\Content\Struct\RichSnippetStruct;
  14. use Shopware\Core\Content\Cms\Aggregate\CmsSection\CmsSectionEntity;
  15. use Shopware\Core\Content\Cms\Aggregate\CmsSlot\CmsSlotCollection;
  16. use Shopware\Core\Content\Cms\Aggregate\CmsSlot\CmsSlotEntity;
  17. use Shopware\Core\System\SystemConfig\SystemConfigService;
  18. use Shopware\Development\Kernel;
  19. use Shopware\Storefront\Event\StorefrontRenderEvent;
  20. use Shopware\Storefront\Page\Navigation\NavigationPage;
  21. use Shopware\Storefront\Page\Product\ProductPage;
  22. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  23. use Symfony\Component\HttpKernel\Event\KernelEvent;
  24. class StorefrontPageLoadedEvent implements EventSubscriberInterface
  25. {
  26.     /**
  27.      * @var SystemConfigService
  28.      */
  29.     private $configService;
  30.     public function __construct(SystemConfigService $configService)
  31.     {
  32.         $this->configService $configService;
  33.     }
  34.     public static function getSubscribedEvents(): array
  35.     {
  36.         return [
  37.             StorefrontRenderEvent::class => 'onStorefrontRender'
  38.         ];
  39.     }
  40.     public function onStorefrontRender(StorefrontRenderEvent $event)
  41.     {
  42.         if ($this->configService->get('LoyxxSW6SeoFaqManager.config.useJsonLd')) {
  43.             /** @var NavigationPage|ProductPage|null $page */
  44.             $page $event->getParameters()['page'] ?? NULL;
  45.             if (!is_null($page) && ($page instanceof NavigationPage || $page instanceof ProductPage)) {
  46.                 $faqs $page instanceof NavigationPage $this->_getFaqsFromNavigationPage($page) : $this->_getFaqsFromDetailPage($page);
  47.                 if ($faqs) {
  48.                     $event->getSalesChannelContext()->setExtensions(["faqJsonLd" => new RichSnippetStruct($this->_prepareJsonLdSnippet($faqs))]);
  49.                 }
  50.             }
  51.         }
  52.     }
  53.     private function _getFaqsFromNavigationPage(NavigationPage $page): array
  54.     {
  55.         $sections $page->getCmsPage()->getSections();
  56.         $faqs = [];
  57.         /** @var CmsSectionEntity $section */
  58.         foreach ($sections as $section) {
  59.             if ($section->getBlocks()->count()) {
  60.                 /** @var CmsSlotCollection $categorySeoFaq */
  61.                 $categorySeoFaq $section->getBlocks()->getSlots()->filter(function (CmsSlotEntity $slot) {
  62.                     return $slot && $slot->getSlot() === 'categorySeoFaq';
  63.                 });
  64.                 if ($categorySeoFaq->count()) {
  65.                     $slotData $categorySeoFaq->getSlot('categorySeoFaq')->getData();
  66.                     if ($slotData instanceof CategorySeoFaqStruct) {
  67.                         /** @var FaqCategoryCollection $faq */
  68.                         $faq $slotData->getCategory()->getExtension('faq');
  69.                         if ($faq->count()) {
  70.                             /** @var FaqCategoryEntity $item */
  71.                             foreach ($faq as $item) {
  72.                                 $faqs array_merge($faqs$item->getItems()->getElements());
  73.                             }
  74.                         }
  75.                         /** @var FaqSetCollection $faqSets */
  76.                         $faqSets $slotData->getCategory()->getExtension('faqSets');
  77.                         if ($faqSets->count()) {
  78.                             /** @var FaqSetEntity $item */
  79.                             foreach ($faqSets as $item) {
  80.                                 $faqs array_merge($faqs$item->getItems()->getElements());
  81.                             }
  82.                         }
  83.                     }
  84.                 }
  85.             }
  86.         }
  87.         return $faqs;
  88.     }
  89.     private function _getFaqsFromDetailPage(ProductPage $page): array
  90.     {
  91.         $faqs = [];
  92.         /** @var FaqProductCollection $faq */
  93.         $faq $page->getProduct()->getExtension('faq');
  94.         if ($faq->count()) {
  95.             /** @var FaqProductEntity $item */
  96.             foreach ($faq as $item) {
  97.                 $faqs array_merge($faqs$item->getItems()->getElements());
  98.             }
  99.         }
  100.         /** @var FaqSetCollection $faqSets */
  101.         $faqSets $page->getProduct()->getExtension('faqSets');
  102.         if ($faqSets->count()) {
  103.             /** @var FaqSetEntity $item */
  104.             foreach ($faqSets as $item) {
  105.                 $faqs array_merge($faqs$item->getItems()->getElements());
  106.             }
  107.         }
  108.         return $faqs;
  109.     }
  110.     private function _prepareJsonLdSnippet(array $faqs) : array
  111.     {
  112.         $snippet = [
  113.             "@context" => "https://schema.org",
  114.             "@type" => "FAQPage",
  115.             "mainEntity" => []
  116.         ];
  117.         /** @var FaqCategoryItemEntity|FaqProductItemEntity|FaqSetItemEntity $faq */
  118.         foreach ($faqs as $faq) {
  119.             $snippet['mainEntity'][] = [
  120.                 "@type" => "Question",
  121.                 "name" => $faq->getTranslation('question'),
  122.                 "acceptedAnswer" => [
  123.                     "@type" => "Answer",
  124.                     "text" => $faq->getTranslation('answer')
  125.                 ]
  126.             ];
  127.         }
  128.         return $snippet;
  129.     }
  130. }