vendor/contao/core-bundle/src/Resources/contao/classes/FrontendTemplate.php line 43

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of Contao.
  4.  *
  5.  * (c) Leo Feyer
  6.  *
  7.  * @license LGPL-3.0-or-later
  8.  */
  9. namespace Contao;
  10. use Symfony\Component\HttpFoundation\Response;
  11. /**
  12.  * Class FrontendTemplate
  13.  *
  14.  * @property integer $id
  15.  * @property string  $keywords
  16.  * @property string  $content
  17.  * @property array   $sections
  18.  * @property array   $positions
  19.  * @property array   $matches
  20.  * @property string  $tag
  21.  */
  22. class FrontendTemplate extends Template
  23. {
  24.     use FrontendTemplateTrait;
  25.     /**
  26.      * Unused $_GET check
  27.      * @var boolean
  28.      */
  29.     protected $blnCheckRequest false;
  30.     /**
  31.      * Add a hook to modify the template output
  32.      *
  33.      * @return string The template markup
  34.      */
  35.     public function parse()
  36.     {
  37.         $strBuffer parent::parse();
  38.         // HOOK: add custom parse filters
  39.         if (isset($GLOBALS['TL_HOOKS']['parseFrontendTemplate']) && \is_array($GLOBALS['TL_HOOKS']['parseFrontendTemplate']))
  40.         {
  41.             foreach ($GLOBALS['TL_HOOKS']['parseFrontendTemplate'] as $callback)
  42.             {
  43.                 $this->import($callback[0]);
  44.                 $strBuffer $this->{$callback[0]}->{$callback[1]}($strBuffer$this->strTemplate$this);
  45.             }
  46.         }
  47.         return $strBuffer;
  48.     }
  49.     /**
  50.      * Send the response to the client
  51.      *
  52.      * @param bool $blnCheckRequest If true, check for unused $_GET parameters
  53.      *
  54.      * @deprecated Deprecated since Contao 4.0, to be removed in Contao 5.0.
  55.      *             Use FrontendTemplate::getResponse() instead.
  56.      */
  57.     public function output($blnCheckRequest=false)
  58.     {
  59.         $this->blnCheckRequest $blnCheckRequest;
  60.         parent::output();
  61.     }
  62.     /**
  63.      * Return a response object
  64.      *
  65.      * @param bool $blnCheckRequest      If true, check for unused $_GET parameters
  66.      * @param bool $blnForceCacheHeaders
  67.      *
  68.      * @return Response The response object
  69.      */
  70.     public function getResponse($blnCheckRequest=false$blnForceCacheHeaders=false)
  71.     {
  72.         $this->blnCheckRequest $blnCheckRequest;
  73.         $response parent::getResponse();
  74.         if ($blnForceCacheHeaders || === strncmp('fe_'$this->strTemplate3))
  75.         {
  76.             return $this->setCacheHeaders($response);
  77.         }
  78.         return $response;
  79.     }
  80.     /**
  81.      * Compile the template
  82.      *
  83.      * @throws UnusedArgumentsException If there are unused $_GET parameters
  84.      *
  85.      * @internal Do not call this method in your code. It will be made private in Contao 5.0.
  86.      */
  87.     protected function compile()
  88.     {
  89.         $this->keywords '';
  90.         // Backwards compatibility
  91.         $arrKeywords StringUtil::trimsplit(','$GLOBALS['TL_KEYWORDS'] ?? '');
  92.         // Add the meta keywords
  93.         if (isset($arrKeywords[0]))
  94.         {
  95.             $this->keywords str_replace(array("\n""\r"'"'), array(' '''''), implode(', 'array_unique($arrKeywords)));
  96.         }
  97.         // Parse the template
  98.         $this->strBuffer $this->parse();
  99.         // HOOK: add custom output filters
  100.         if (isset($GLOBALS['TL_HOOKS']['outputFrontendTemplate']) && \is_array($GLOBALS['TL_HOOKS']['outputFrontendTemplate']))
  101.         {
  102.             foreach ($GLOBALS['TL_HOOKS']['outputFrontendTemplate'] as $callback)
  103.             {
  104.                 $this->import($callback[0]);
  105.                 $this->strBuffer $this->{$callback[0]}->{$callback[1]}($this->strBuffer$this->strTemplate);
  106.             }
  107.         }
  108.         $this->strBuffer System::getContainer()->get('contao.insert_tag.parser')->replace($this->strBuffer);
  109.         $this->strBuffer $this->replaceDynamicScriptTags($this->strBuffer); // see #4203
  110.         // HOOK: allow to modify the compiled markup (see #4291)
  111.         if (isset($GLOBALS['TL_HOOKS']['modifyFrontendPage']) && \is_array($GLOBALS['TL_HOOKS']['modifyFrontendPage']))
  112.         {
  113.             foreach ($GLOBALS['TL_HOOKS']['modifyFrontendPage'] as $callback)
  114.             {
  115.                 $this->import($callback[0]);
  116.                 $this->strBuffer $this->{$callback[0]}->{$callback[1]}($this->strBuffer$this->strTemplate);
  117.             }
  118.         }
  119.         // Check whether all $_GET parameters have been used (see #4277)
  120.         if ($this->blnCheckRequest && Input::hasUnusedGet())
  121.         {
  122.             throw new UnusedArgumentsException('Unused arguments: ' implode(', 'Input::getUnusedGet()));
  123.         }
  124.         /** @var PageModel|null $objPage */
  125.         global $objPage;
  126.         // Minify the markup
  127.         if ($objPage !== null && $objPage->minifyMarkup)
  128.         {
  129.             $this->strBuffer $this->minifyHtml($this->strBuffer);
  130.         }
  131.         // Replace literal insert tags (see #670, #3249)
  132.         $this->strBuffer preg_replace_callback(
  133.             '/<script[^>]*>.*?<\/script[^>]*>|\[[{}]]/is',
  134.             static function ($matches)
  135.             {
  136.                 return $matches[0][0] === '<' $matches[0] : '&#' . \ord($matches[0][1]) . ';&#' . \ord($matches[0][1]) . ';';
  137.             },
  138.             $this->strBuffer
  139.         );
  140.         parent::compile();
  141.     }
  142.     /**
  143.      * Set the cache headers according to the page settings.
  144.      *
  145.      * @param Response $response The response object
  146.      *
  147.      * @return Response The response object
  148.      */
  149.     private function setCacheHeaders(Response $response)
  150.     {
  151.         /** @var PageModel $objPage */
  152.         global $objPage;
  153.         // Do not cache the response if caching was not configured at all or disabled explicitly
  154.         if (($objPage->cache === false || $objPage->cache 1) && ($objPage->clientCache === false || $objPage->clientCache 1))
  155.         {
  156.             $response->headers->set('Cache-Control''no-cache, no-store');
  157.             return $response->setPrivate(); // Make sure the response is private
  158.         }
  159.         // Private cache
  160.         if ($objPage->clientCache 0)
  161.         {
  162.             $response->setMaxAge($objPage->clientCache);
  163.             $response->setPrivate(); // Make sure the response is private
  164.         }
  165.         // Shared cache
  166.         if ($objPage->cache 0)
  167.         {
  168.             $response->setSharedMaxAge($objPage->cache); // Automatically sets the response to public
  169.             // We vary on cookies if a response is cacheable by the shared
  170.             // cache, so a reverse proxy does not load a response from cache if
  171.             // the _request_ contains a cookie.
  172.             //
  173.             // This DOES NOT mean that we generate a cache entry for every
  174.             // response containing a cookie! Responses with cookies will always
  175.             // be private (@see Contao\CoreBundle\EventListener\MakeResponsePrivateListener).
  176.             //
  177.             // However, we want to be able to force the reverse proxy to load a
  178.             // response from cache, even if the request contains a cookie – in
  179.             // case the admin has configured to do so. A typical use case would
  180.             // be serving public pages from cache to logged in members.
  181.             if (!$objPage->alwaysLoadFromCache)
  182.             {
  183.                 $response->setVary(array('Cookie'));
  184.             }
  185.             // Tag the page (see #2137)
  186.             System::getContainer()->get('contao.cache.entity_tags')->tagWithModelInstance($objPage);
  187.         }
  188.         return $response;
  189.     }
  190. }
  191. class_alias(FrontendTemplate::class, 'FrontendTemplate');