vendor/shopware/core/Content/Cms/SalesChannel/SalesChannelCmsPageLoader.php line 46

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Content\Cms\SalesChannel;
  3. use Shopware\Core\Content\Cms\Aggregate\CmsBlock\CmsBlockEntity;
  4. use Shopware\Core\Content\Cms\Aggregate\CmsSection\CmsSectionEntity;
  5. use Shopware\Core\Content\Cms\CmsPageEntity;
  6. use Shopware\Core\Content\Cms\DataResolver\CmsSlotsDataResolver;
  7. use Shopware\Core\Content\Cms\DataResolver\ResolverContext\ResolverContext;
  8. use Shopware\Core\Content\Cms\Events\CmsPageLoadedEvent;
  9. use Shopware\Core\Content\Cms\Events\CmsPageLoaderCriteriaEvent;
  10. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
  13. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  14. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  15. use Symfony\Component\HttpFoundation\Request;
  16. class SalesChannelCmsPageLoader implements SalesChannelCmsPageLoaderInterface
  17. {
  18.     /**
  19.      * @var EntityRepositoryInterface
  20.      */
  21.     private $cmsPageRepository;
  22.     /**
  23.      * @var CmsSlotsDataResolver
  24.      */
  25.     private $slotDataResolver;
  26.     /**
  27.      * @var EventDispatcherInterface
  28.      */
  29.     private $eventDispatcher;
  30.     public function __construct(
  31.         EntityRepositoryInterface $cmsPageRepository,
  32.         CmsSlotsDataResolver $slotDataResolver,
  33.         EventDispatcherInterface $eventDispatcher
  34.     ) {
  35.         $this->cmsPageRepository $cmsPageRepository;
  36.         $this->slotDataResolver $slotDataResolver;
  37.         $this->eventDispatcher $eventDispatcher;
  38.     }
  39.     public function load(
  40.         Request $request,
  41.         Criteria $criteria,
  42.         SalesChannelContext $context,
  43.         ?array $config null,
  44.         ?ResolverContext $resolverContext null
  45.     ): EntitySearchResult {
  46.         $this->eventDispatcher->dispatch(new CmsPageLoaderCriteriaEvent($request$criteria$context));
  47.         $config $config ?? [];
  48.         // ensure sections, blocks and slots are loaded, slots and blocks can be restricted by caller
  49.         $criteria
  50.             ->getAssociation('sections')
  51.             ->addAssociation('backgroundMedia');
  52.         $criteria
  53.             ->getAssociation('sections.blocks')
  54.             ->addAssociation('backgroundMedia')
  55.             ->addAssociation('slots');
  56.         // step 1, load cms pages with blocks and slots
  57.         $pages $this->cmsPageRepository->search($criteria$context->getContext());
  58.         /** @var CmsPageEntity $page */
  59.         foreach ($pages as $page) {
  60.             if (!$page->getSections()) {
  61.                 continue;
  62.             }
  63.             $page->getSections()->sort(function (CmsSectionEntity $aCmsSectionEntity $b) {
  64.                 return $a->getPosition() <=> $b->getPosition();
  65.             });
  66.             if (!$resolverContext) {
  67.                 $resolverContext = new ResolverContext($context$request);
  68.             }
  69.             // step 2, sort blocks into sectionPositions
  70.             foreach ($page->getSections() as $section) {
  71.                 $section->getBlocks()->sort(function (CmsBlockEntity $aCmsBlockEntity $b) {
  72.                     return $a->getPosition() <=> $b->getPosition();
  73.                 });
  74.             }
  75.             // step 3, find config overwrite
  76.             $overwrite $config[$page->getId()] ?? $config;
  77.             // step 4, overwrite slot config
  78.             $this->overwriteSlotConfig($page$overwrite);
  79.             // step 5, resolve slot data
  80.             $this->loadSlotData($page$resolverContext);
  81.         }
  82.         $this->eventDispatcher->dispatch(new CmsPageLoadedEvent($request$pages->getEntities(), $context));
  83.         return $pages;
  84.     }
  85.     private function loadSlotData(CmsPageEntity $pageResolverContext $resolverContext): void
  86.     {
  87.         $slots $this->slotDataResolver->resolve($page->getSections()->getBlocks()->getSlots(), $resolverContext);
  88.         $page->getSections()->getBlocks()->setSlots($slots);
  89.     }
  90.     private function overwriteSlotConfig(CmsPageEntity $page, array $config): void
  91.     {
  92.         foreach ($page->getSections()->getBlocks()->getSlots() as $slot) {
  93.             if ($slot->getConfig() === null && $slot->getTranslation('config') !== null) {
  94.                 $slot->setConfig($slot->getTranslation('config'));
  95.             }
  96.             if (empty($config)) {
  97.                 continue;
  98.             }
  99.             if (!isset($config[$slot->getId()])) {
  100.                 continue;
  101.             }
  102.             $defaultConfig $slot->getConfig() ?? [];
  103.             $merged array_replace_recursive(
  104.                 $defaultConfig,
  105.                 $config[$slot->getId()]
  106.             );
  107.             $slot->setConfig($merged);
  108.             $slot->addTranslated('config'$merged);
  109.         }
  110.     }
  111. }