src/Renderer/Page.php line 272

Open in your IDE?
  1. <?php
  2. namespace App\Renderer;
  3. use App\Component\Configuration\Util\Config;
  4. use App\Entity\Asset;
  5. use App\Entity\HeroConfiguration;
  6. use App\Entity\OgImage;
  7. use App\Entity\Page as PageEntity;
  8. use App\Entity\Review;
  9. use App\Entity\Route;
  10. use App\Entity\Taggable;
  11. use App\Event\PageEvent;
  12. use App\EventListener\FeatureFlagListener;
  13. use App\Model\Tealium\Base as TealiumBase;
  14. use App\Util\Breadcrumb;
  15. use App\Util\BreadcrumbableInterface;
  16. use App\Util\CookiescriptHelper;
  17. use App\Util\Seo;
  18. use Doctrine\ORM\EntityManagerInterface;
  19. use Flagception\Manager\FeatureManagerInterface;
  20. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  21. use Symfony\Component\HttpFoundation\Request;
  22. use Symfony\Component\HttpFoundation\RequestStack;
  23. use Symfony\Component\HttpFoundation\Response;
  24. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  25. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  26. use Twig\Environment as Twig_Environment;
  27. use Twig\Error\LoaderError;
  28. use Twig\Error\RuntimeError;
  29. use Twig\Error\SyntaxError;
  30. class Page
  31. {
  32.     private EntityManagerInterface $entityManager;
  33.     private Twig_Environment $twig;
  34.     private Breadcrumb $breadcrumbUtil;
  35.     private ?Request $request;
  36.     protected Seo $seoUtil;
  37.     private FeatureManagerInterface $featureManager;
  38.     private ParameterBagInterface $parameterBag;
  39.     private EventDispatcherInterface $eventDispatcher;
  40.     private ?object $entity null;
  41.     private Config $config;
  42.     /**
  43.      * Page constructor.
  44.      */
  45.     public function __construct(
  46.         EntityManagerInterface $entityManager,
  47.         Twig_Environment $twig,
  48.         RequestStack $requestStack,
  49.         Breadcrumb $breadcrumb,
  50.         Seo $seoUtil,
  51.         FeatureManagerInterface $featureManager,
  52.         ParameterBagInterface $parameterBag,
  53.         EventDispatcherInterface $eventDispatcher,
  54.         Config $config
  55.     ) {
  56.         $this->entityManager $entityManager;
  57.         $this->twig $twig;
  58.         $this->breadcrumbUtil $breadcrumb;
  59.         $this->request $requestStack->getCurrentRequest();
  60.         $this->seoUtil $seoUtil;
  61.         $this->featureManager $featureManager;
  62.         $this->parameterBag $parameterBag;
  63.         $this->eventDispatcher $eventDispatcher;
  64.         $this->config $config;
  65.     }
  66.     public function renderSystemPage(PageEntity $page): Response
  67.     {
  68.         $content $this->twig->render('@default/pages/pages_index.html.twig', [
  69.             'header' => $this->getHeader($page),
  70.             'footer' => $this->getFooter(),
  71.             'page' => $page,
  72.         ]);
  73.         return new Response($content);
  74.     }
  75.     /**
  76.      * @param Asset|HeroConfiguration|string|null $hero
  77.      *
  78.      * @throws LoaderError
  79.      * @throws RuntimeError
  80.      * @throws SyntaxError
  81.      */
  82.     public function renderPage(
  83.         string $placeholder,
  84.         string $template,
  85.         array $data,
  86.         array $canonicals = [],
  87.         array $metaData = [],
  88.         ?BreadcrumbableInterface $breadcrumbEntity null,
  89.         ?Route $route null,
  90.         mixed $hero null,
  91.         array $options = []
  92.     ): Response {
  93.         if (!$route) {
  94.             $route $this->entityManager
  95.                 ->getRepository(Route::class)
  96.                 ->findOneBy(['name' => $this->request->get('_route')])
  97.             ;
  98.         }
  99.         // if route is not found, throw NotFoundHttpException
  100.         if (!$route) {
  101.             throw new NotFoundHttpException('Page not found');
  102.         }
  103.         /** @var PageEntity $page */
  104.         $page $route->getPage();
  105.         if ($page->getFeature() && !$this->featureManager->isActive($page->getFeature())) {
  106.             throw new NotFoundHttpException();
  107.         }
  108.         $page->setBreadcrumbEntity($breadcrumbEntity);
  109.         $breadcrumbs $this->breadcrumbUtil->getBreadcrumbsForPage($page$breadcrumbEntity);
  110.         if ($breadcrumbEntity && $breadcrumbEntity->getBreadcrumbTitle()) {
  111.             $page->setTitle($breadcrumbEntity->getBreadcrumbTitle());
  112.         }
  113.         $defaultOgImage null;
  114.         if ($ogImage $this->config->get('site_open_graph_image')) {
  115.             $defaultOgImage = (new OgImage())->setImage($ogImage);
  116.         }
  117.         $this->seoUtil->setSeoInformationForPage(
  118.             $metaData,
  119.             $page,
  120.             $defaultOgImage
  121.         );
  122.         if ($hero instanceof Asset) {
  123.             $hero $this->twig->render('@default/pages/hero.html.twig', ['hero' => $hero]);
  124.         } elseif ($hero instanceof HeroConfiguration) {
  125.             $hero $this->twig->render('@default/pages/hero_configuration.html.twig', [
  126.                 'heroConfiguration' => $hero,
  127.             ]);
  128.         } elseif ($page->getHeroConfiguration() instanceof HeroConfiguration) {
  129.             $hero $this->twig->render('@default/pages/hero_configuration.html.twig', [
  130.                     'heroConfiguration' => $page->getHeroConfiguration(),
  131.             ]);
  132.         } elseif (\is_string($hero) && '' !== $hero) {
  133.             $hero $this->twig->render('@default/pages/hero_as_string.html.twig', ['hero' => $hero]);
  134.         }
  135.         $this->eventDispatcher->dispatch(
  136.             new PageEvent($page$this->entity$metaData$this->request),
  137.             PageEvent::PAGE_BEFORE_RENDER
  138.         );
  139.         if (\array_key_exists('robots'$options)
  140.             && \is_string($options['robots'])
  141.             && '' !== $options['robots']
  142.         ) {
  143.             $page->setRobots($options['robots']);
  144.         }
  145.         $scripts '';
  146.         if (\array_key_exists('jobPostingStructuredData'$data)
  147.             && \is_string($data['jobPostingStructuredData'])
  148.             && '' !== $data['jobPostingStructuredData']
  149.         ) {
  150.             $scripts .= $this->twig->render(
  151.                 'page/vacancy/job_posting_structered_data.html.twig',
  152.                 ['jobPostingStructuredData' => $data['jobPostingStructuredData']]
  153.             );
  154.         }
  155.         $tealium TealiumBase::createForPage($this->request$page$route);
  156.         if ($this->entity) {
  157.             $tealium->removeProperty('page_id')
  158.                 ->addProperty('page_id'sprintf('%s_%s'$route->getName(), $this->entity->getId()))
  159.             ;
  160.             if ($this->entity instanceof Taggable && $this->entity->getTags()) {
  161.                 $tealium->removeProperty('page_tags')
  162.                     ->addProperty('page_tags'array_map('strval'$this->entity->getTags()->toArray()))
  163.                 ;
  164.             }
  165.         }
  166.         if (\array_key_exists('tealium_element'$options) && $options['tealium_element'] instanceof TealiumBase) {
  167.             $tealium->merge($options['tealium_element']);
  168.         }
  169.         if ($this->featureManager->isActive(FeatureFlagListener::FEATURE_THEME_INHERITANCE)) {
  170.             $content $this->twig->render($templatearray_merge($data, [
  171.                 'header' => $this->getHeader($page),
  172.                 'footer' => $this->getFooter(),
  173.                 'page' => $page,
  174.                 'breadcrumbs' => $breadcrumbs,
  175.                 'canonicals' => $canonicals,
  176.                 'hero' => $hero,
  177.                 'scripts' => $scripts,
  178.                 'tealium_data' => $tealium->toJson(),
  179.                 'tealium_push_directly' => !\array_key_exists('skip_tealium'$options) || !$options['skip_tealium'],
  180.             ]));
  181.             $response = new Response($content);
  182.         } else {
  183.             $body str_replace(
  184.                 $placeholder,
  185.                 $this->twig->render(
  186.                     $template,
  187.                     array_merge($data, [
  188.                         'page' => $page,
  189.                         'breadcrumbs' => $breadcrumbs,
  190.                     ])
  191.                 ),
  192.                 $page->getBody()
  193.             );
  194.             $page->setBody($body);
  195.             $this->entityManager->clear(PageEntity::class);
  196.             $response = new Response($this->twig->render(
  197.                 '@default/pages/pages_index.html.twig',
  198.                 array_merge($data, [
  199.                     'header' => $this->getHeader($page),
  200.                     'footer' => $this->getFooter(),
  201.                     'page' => $page,
  202.                     'canonicals' => $canonicals,
  203.                     'breadcrumbs' => $breadcrumbs,
  204.                     'hero' => $hero,
  205.                     'scripts' => $scripts,
  206.                 ])
  207.             ));
  208.         }
  209.         $response->setContent(
  210.             CookiescriptHelper::cookiefyMarkup($response->getContent())
  211.         );
  212.         $this->entity null;
  213.         return $response;
  214.     }
  215.     public function getHeader(?PageEntity $activePage null): string
  216.     {
  217.         $pageRepository $this->entityManager->getRepository(PageEntity::class);
  218.         if ($this->parameterBag->get('site_translation_multiple_locales')) {
  219.             $pageRepository->setMultilingual(true);
  220.         }
  221.         $reviews = [];
  222.         $scores = [];
  223.         if ($this->featureManager->isActive(FeatureFlagListener::FEATURE_REVIEW)) {
  224.             $reviews $this->entityManager->getRepository(Review::class)->findAll();
  225.             $scores array_map(static function (Review $review) {
  226.                 return $review->getScore();
  227.             }, $reviews);
  228.         }
  229.         $averageScore 0;
  230.         if ($reviews && $scores) {
  231.             $averageScore array_sum($scores) / \count($reviews);
  232.         }
  233.         try {
  234.             $response $this->twig->render('@default/pages/pages_header.html.twig', [
  235.                 'pages' => $pageRepository->getHeaderNavigation(),
  236.                 'topNavigation' => $pageRepository->getTopNavigation(),
  237.                 'averageScore' => $averageScore,
  238.                 'reviews' => $reviews,
  239.                 'activePage' => $activePage,
  240.             ]);
  241.         } catch (\Exception) {
  242.             $response '';
  243.         }
  244.         return $response;
  245.     }
  246.     public function getFooter(): string
  247.     {
  248.         $pageRepository $this->entityManager->getRepository(PageEntity::class);
  249.         if ($this->parameterBag->get('site_translation_multiple_locales')) {
  250.             $pageRepository->setMultilingual(true);
  251.         }
  252.         try {
  253.             $response $this->twig->render(
  254.                 '@default/pages/pages_footer.html.twig',
  255.                 [
  256.                     'pages' => $pageRepository->getFooterNavigation(),
  257.                     'footer_bottom_pages' => $pageRepository->getFooterBottomNavigation(),
  258.                     'header_pages' => $pageRepository->getHeaderNavigation(),
  259.                 ]
  260.             );
  261.         } catch (\Exception) {
  262.             $response '';
  263.         }
  264.         return $response;
  265.     }
  266.     public function withEntity(object $entity): self
  267.     {
  268.         $this->entity $entity;
  269.         return $this;
  270.     }
  271. }