src/Renderer/Page.php line 269

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.         $scripts '';
  140.         if (\array_key_exists('jobPostingStructuredData'$data)
  141.             && \is_string($data['jobPostingStructuredData'])
  142.             && '' !== $data['jobPostingStructuredData']
  143.         ) {
  144.             $scripts .= $this->twig->render(
  145.                 'page/vacancy/job_posting_structered_data.html.twig',
  146.                 ['jobPostingStructuredData' => $data['jobPostingStructuredData']]
  147.             );
  148.         }
  149.         $tealium TealiumBase::createForPage($this->request$page$route);
  150.         if ($this->entity) {
  151.             $tealium->removeProperty('page_id')
  152.                 ->addProperty('page_id'sprintf('%s_%s'$route->getName(), $this->entity->getId()))
  153.             ;
  154.             if ($this->entity instanceof Taggable && $this->entity->getTags()) {
  155.                 $tealium->removeProperty('page_tags')
  156.                     ->addProperty('page_tags'array_map('strval'$this->entity->getTags()->toArray()))
  157.                 ;
  158.             }
  159.         }
  160.         if (\array_key_exists('tealium_element'$options) && $options['tealium_element'] instanceof TealiumBase) {
  161.             $tealium->merge($options['tealium_element']);
  162.         }
  163.         if ($this->featureManager->isActive(FeatureFlagListener::FEATURE_THEME_INHERITANCE)) {
  164.             $content $this->twig->render($templatearray_merge($data, [
  165.                 'header' => $this->getHeader($page),
  166.                 'footer' => $this->getFooter(),
  167.                 'page' => $page,
  168.                 'breadcrumbs' => $breadcrumbs,
  169.                 'canonicals' => $canonicals,
  170.                 'hero' => $hero,
  171.                 'scripts' => $scripts,
  172.                 'tealium_data' => $tealium->toJson(),
  173.                 'tealium_push_directly' => !\array_key_exists('skip_tealium'$options) || !$options['skip_tealium'],
  174.             ]));
  175.             $response = new Response($content);
  176.         } else {
  177.             $body str_replace(
  178.                 $placeholder,
  179.                 $this->twig->render(
  180.                     $template,
  181.                     array_merge($data, [
  182.                         'page' => $page,
  183.                         'breadcrumbs' => $breadcrumbs,
  184.                     ])
  185.                 ),
  186.                 $page->getBody()
  187.             );
  188.             $page->setBody($body);
  189.             $this->entityManager->clear(PageEntity::class);
  190.             $response = new Response($this->twig->render(
  191.                 '@default/pages/pages_index.html.twig',
  192.                 array_merge($data, [
  193.                     'header' => $this->getHeader($page),
  194.                     'footer' => $this->getFooter(),
  195.                     'page' => $page,
  196.                     'canonicals' => $canonicals,
  197.                     'breadcrumbs' => $breadcrumbs,
  198.                     'hero' => $hero,
  199.                     'scripts' => $scripts,
  200.                 ])
  201.             ));
  202.         }
  203.         $response->setContent(
  204.             CookiescriptHelper::cookiefyMarkup($response->getContent())
  205.         );
  206.         $this->eventDispatcher->dispatch(
  207.             new ResponseCreatedByPageRenderer($page$this->entity$response)
  208.         );
  209.         $this->entity null;
  210.         return $response;
  211.     }
  212.     public function getHeader(?PageEntity $activePage null): string
  213.     {
  214.         $pageRepository $this->entityManager->getRepository(PageEntity::class);
  215.         if ($this->parameterBag->get('site_translation_multiple_locales')) {
  216.             $pageRepository->setMultilingual(true);
  217.         }
  218.         $reviews = [];
  219.         $scores = [];
  220.         if ($this->featureManager->isActive(FeatureFlagListener::FEATURE_REVIEW)) {
  221.             $reviews $this->entityManager->getRepository(Review::class)->findAll();
  222.             $scores array_map(static function (Review $review) {
  223.                 return $review->getScore();
  224.             }, $reviews);
  225.         }
  226.         $averageScore 0;
  227.         if ($reviews && $scores) {
  228.             $averageScore array_sum($scores) / \count($reviews);
  229.         }
  230.         try {
  231.             $response $this->twig->render('@default/pages/pages_header.html.twig', [
  232.                 'pages' => $pageRepository->getHeaderNavigation(),
  233.                 'topNavigation' => $pageRepository->getTopNavigation(),
  234.                 'averageScore' => $averageScore,
  235.                 'reviews' => $reviews,
  236.                 'activePage' => $activePage,
  237.             ]);
  238.         } catch (\Exception) {
  239.             $response '';
  240.         }
  241.         return $response;
  242.     }
  243.     public function getFooter(): string
  244.     {
  245.         $pageRepository $this->entityManager->getRepository(PageEntity::class);
  246.         if ($this->parameterBag->get('site_translation_multiple_locales')) {
  247.             $pageRepository->setMultilingual(true);
  248.         }
  249.         try {
  250.             $response $this->twig->render(
  251.                 '@default/pages/pages_footer.html.twig',
  252.                 [
  253.                     'pages' => $pageRepository->getFooterNavigation(),
  254.                     'footer_bottom_pages' => $pageRepository->getFooterBottomNavigation(),
  255.                     'header_pages' => $pageRepository->getHeaderNavigation(),
  256.                 ]
  257.             );
  258.         } catch (\Exception) {
  259.             $response '';
  260.         }
  261.         return $response;
  262.     }
  263.     public function withEntity(object $entity): self
  264.     {
  265.         $this->entity $entity;
  266.         return $this;
  267.     }
  268. }