custom/plugins/ShopStudioBlog/src/Storefront/Page/BlogPost/BlogPostPageLoader.php line 101

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace ShopStudio\Blog\Storefront\Page\BlogPost;
  3. use ShopStudio\Blog\Content\BlogPost\BlogPostDefinition;
  4. use ShopStudio\Blog\Content\BlogPost\BlogPostEntity;
  5. use ShopStudio\Blog\Content\BlogPost\Exception\BlogPostNotFoundException;
  6. use ShopStudio\Blog\Content\BlogPost\SalesChannel\Detail\AbstractBlogPostDetailRoute;
  7. use ShopStudio\Blog\Storefront\Page\BlogPost\Comment\BlogPostCommentLoader;
  8. use Shopware\Core\Content\Category\Exception\CategoryNotFoundException;
  9. use Shopware\Core\Content\Cms\CmsPageEntity;
  10. use Shopware\Core\Content\Cms\DataResolver\CmsSlotsDataResolver;
  11. use Shopware\Core\Content\Cms\DataResolver\ResolverContext\EntityResolverContext;
  12. use Shopware\Core\Content\Cms\SalesChannel\SalesChannelCmsPageRepository;
  13. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
  17. use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
  18. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  19. use Shopware\Storefront\Page\GenericPageLoader;
  20. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  21. use Symfony\Component\HttpFoundation\Request;
  22. /**
  23.  * @since 1.0.0
  24.  */
  25. class BlogPostPageLoader
  26. {
  27.     /**
  28.      * @since 1.0.0
  29.      */
  30.     private GenericPageLoader $genericLoader;
  31.     /**
  32.      * @since 1.0.0
  33.      */
  34.     private EntityRepositoryInterface $blogPostRepository;
  35.     /**
  36.      * @since 1.0.0
  37.      */
  38.     private EventDispatcherInterface $eventDispatcher;
  39.     /**
  40.      * @since 1.0.0
  41.      */
  42.     private SalesChannelCmsPageRepository $cmsPageRepository;
  43.     /**
  44.      * @since 1.0.0
  45.      */
  46.     private CmsSlotsDataResolver $slotDataResolver;
  47.     /**
  48.      * @since 1.0.0
  49.      */
  50.     private BlogPostDefinition $blogPostDefinition;
  51.     /**
  52.      * @since 2.0.0
  53.      */
  54.     private AbstractBlogPostDetailRoute $blogPostDetailRoute;
  55.     /**
  56.      * @since 1.0.0
  57.      */
  58.     private BlogPostCommentLoader $blogPostCommentLoader;
  59.     /**
  60.      * @since 2.0.0
  61.      */
  62.     public function __construct(
  63.         GenericPageLoader $genericLoader,
  64.         EntityRepositoryInterface $blogPostRepository,
  65.         EventDispatcherInterface $eventDispatcher,
  66.         SalesChannelCmsPageRepository $cmsPageRepository,
  67.         CmsSlotsDataResolver $slotDataResolver,
  68.         BlogPostDefinition $blogPostDefinition,
  69.         AbstractBlogPostDetailRoute $blogPostDetailRoute,
  70.         BlogPostCommentLoader $blogPostCommentLoader
  71.     ) {
  72.         $this->genericLoader $genericLoader;
  73.         $this->blogPostRepository $blogPostRepository;
  74.         $this->eventDispatcher $eventDispatcher;
  75.         $this->cmsPageRepository $cmsPageRepository;
  76.         $this->slotDataResolver $slotDataResolver;
  77.         $this->blogPostDefinition $blogPostDefinition;
  78.         $this->blogPostDetailRoute $blogPostDetailRoute;
  79.         $this->blogPostCommentLoader $blogPostCommentLoader;
  80.     }
  81.     /**
  82.      * @since 1.0.0
  83.      *
  84.      * @throws CategoryNotFoundException
  85.      * @throws InconsistentCriteriaIdsException
  86.      * @throws MissingRequestParameterException
  87.      * @throws BlogPostNotFoundException
  88.      */
  89.     public function load(Request $requestSalesChannelContext $salesChannelContext): BlogPostPage
  90.     {
  91.         $page $this->genericLoader->load($request$salesChannelContext);
  92.         $page BlogPostPage::createFrom($page);
  93.         $blogPostId $request->attributes->get('blogPostId');
  94.         if (!$blogPostId) {
  95.             throw new MissingRequestParameterException('blogPostId''/blogPostId');
  96.         }
  97.         $criteria $this->buildCriteria($blogPostId);
  98.         $this->eventDispatcher->dispatch(
  99.             new BlogPostPageCriteriaEvent($blogPostId$criteria$salesChannelContext)
  100.         );
  101.         $blogPostDetailRouteResponse $this->blogPostDetailRoute->load($blogPostId$request$salesChannelContext$criteria);
  102.         $blogPost $blogPostDetailRouteResponse->getBlogPost();
  103.         $page->setBlogPost($blogPost);
  104.         $schema $blogPostDetailRouteResponse->getSchema();
  105.         $page->setSchema($schema);
  106.         $commentLoaderResults $this->blogPostCommentLoader->load($request$salesChannelContext);
  107.         $page->setComments($commentLoaderResults);
  108.         $cmsPage $this->getCmsPage($salesChannelContext);
  109.         if ($cmsPage !== null) {
  110.             $this->loadSlotData($cmsPage$salesChannelContext$blogPost);
  111.             $page->setCmsPage($cmsPage);
  112.         }
  113.         $this->loadMetaData($page);
  114.         $this->eventDispatcher->dispatch(
  115.             new BlogPostPageLoadedEvent($page$salesChannelContext$request)
  116.         );
  117.         return $page;
  118.     }
  119.     /**
  120.      * @since 1.0.0
  121.      */
  122.     private function loadMetaData(BlogPostPage $page): void
  123.     {
  124.         $blogPost $page->getBlogPost();
  125.         $metaInformation $page->getMetaInformation();
  126.         if ($metaInformation === null) {
  127.             $metaInformation = new MetaInformation();
  128.         }
  129.         $metaTitle $blogPost->getTranslation('metaTitle') ?? $blogPost->getTranslation('title');
  130.         $metaInformation->setMetaTitle($metaTitle);
  131.         $metaDescription $blogPost->getTranslation('metaDescription') ?? $blogPost->getTranslation('description');
  132.         $metaInformation->setMetaDescription((string) $metaDescription);
  133.         $keywords $blogPost->getTranslation('keywords');
  134.         $metaInformation->setMetaKeywords((string) $keywords);
  135.         $author $blogPost->getAuthor();
  136.         if (!empty($author)) {
  137.             $metaInformation->setAuthor($author);
  138.         }
  139.     }
  140.     /**
  141.      * @since 1.0.0
  142.      */
  143.     private function loadSlotData(CmsPageEntity $pageSalesChannelContext $salesChannelContextBlogPostEntity $blogPost): void
  144.     {
  145.         if (!$page->getSections()) {
  146.             return;
  147.         }
  148.         $request = new Request();
  149.         $resolverContext = new EntityResolverContext($salesChannelContext$request$this->blogPostDefinition$blogPost);
  150.         foreach ($page->getSections() as $section) {
  151.             $slots $this->slotDataResolver->resolve($section->getBlocks()->getSlots(), $resolverContext);
  152.             $section->getBlocks()->setSlots($slots);
  153.         }
  154.     }
  155.     /**
  156.      * @since 1.0.0
  157.      */
  158.     private function getCmsPage(SalesChannelContext $context): ?CmsPageEntity
  159.     {
  160.         $pages $this->cmsPageRepository->getPagesByType('blog_post_detail'$context);
  161.         if ($pages->count() === 0) {
  162.             return null;
  163.         }
  164.         /** @var CmsPageEntity $page */
  165.         $page $pages->first();
  166.         return $page;
  167.     }
  168.     /**
  169.      * @since 1.0.0
  170.      */
  171.     private function buildCriteria(string $blogPostId): Criteria
  172.     {
  173.         $criteria = (new Criteria([$blogPostId]))
  174.             ->addAssociation('mainImage')
  175.             ->addAssociation('mainCategory')
  176.             ->addAssociation('categories')
  177.             ->addAssociation('salesChannels')
  178.             ->addAssociation('translations')
  179.             ->addAssociation('content')
  180.             ->addAssociation('content.translations')
  181.         ;
  182.         $criteria
  183.             ->getAssociation('content')
  184.             ->addSorting(new FieldSorting('position'FieldSorting::ASCENDING))
  185.         ;
  186.         return $criteria;
  187.     }
  188. }