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

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