[ Index ]

PHP Cross Reference of phpBB-3.3.2-deutsch

title

Body

[close]

/vendor/symfony/twig-bridge/Form/ -> TwigRendererEngine.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of the Symfony package.
   5   *
   6   * (c) Fabien Potencier <fabien@symfony.com>
   7   *
   8   * For the full copyright and license information, please view the LICENSE
   9   * file that was distributed with this source code.
  10   */
  11  
  12  namespace Symfony\Bridge\Twig\Form;
  13  
  14  use Symfony\Component\Form\AbstractRendererEngine;
  15  use Symfony\Component\Form\FormView;
  16  use Twig\Environment;
  17  use Twig\Template;
  18  
  19  /**
  20   * @author Bernhard Schussek <bschussek@gmail.com>
  21   */
  22  class TwigRendererEngine extends AbstractRendererEngine implements TwigRendererEngineInterface
  23  {
  24      /**
  25       * @var Environment
  26       */
  27      private $environment;
  28  
  29      /**
  30       * @var Template
  31       */
  32      private $template;
  33  
  34      public function __construct(array $defaultThemes = [], Environment $environment = null)
  35      {
  36          if (null === $environment) {
  37              @trigger_error(sprintf('Not passing a Twig Environment as the second argument for "%s" constructor is deprecated since Symfony 3.2 and won\'t be possible in 4.0.', static::class), \E_USER_DEPRECATED);
  38          }
  39  
  40          parent::__construct($defaultThemes);
  41          $this->environment = $environment;
  42      }
  43  
  44      /**
  45       * {@inheritdoc}
  46       *
  47       * @deprecated since version 3.3, to be removed in 4.0
  48       */
  49      public function setEnvironment(Environment $environment)
  50      {
  51          if ($this->environment) {
  52              @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 3.3 and will be removed in 4.0. Pass the Twig Environment as second argument of the constructor instead.', __METHOD__), \E_USER_DEPRECATED);
  53          }
  54  
  55          $this->environment = $environment;
  56      }
  57  
  58      /**
  59       * {@inheritdoc}
  60       */
  61      public function renderBlock(FormView $view, $resource, $blockName, array $variables = [])
  62      {
  63          $cacheKey = $view->vars[self::CACHE_KEY_VAR];
  64  
  65          $context = $this->environment->mergeGlobals($variables);
  66  
  67          ob_start();
  68  
  69          // By contract,This method can only be called after getting the resource
  70          // (which is passed to the method). Getting a resource for the first time
  71          // (with an empty cache) is guaranteed to invoke loadResourcesFromTheme(),
  72          // where the property $template is initialized.
  73  
  74          // We do not call renderBlock here to avoid too many nested level calls
  75          // (XDebug limits the level to 100 by default)
  76          $this->template->displayBlock($blockName, $context, $this->resources[$cacheKey]);
  77  
  78          return ob_get_clean();
  79      }
  80  
  81      /**
  82       * Loads the cache with the resource for a given block name.
  83       *
  84       * This implementation eagerly loads all blocks of the themes assigned to the given view
  85       * and all of its ancestors views. This is necessary, because Twig receives the
  86       * list of blocks later. At that point, all blocks must already be loaded, for the
  87       * case that the function "block()" is used in the Twig template.
  88       *
  89       * @see getResourceForBlock()
  90       *
  91       * @param string   $cacheKey  The cache key of the form view
  92       * @param FormView $view      The form view for finding the applying themes
  93       * @param string   $blockName The name of the block to load
  94       *
  95       * @return bool True if the resource could be loaded, false otherwise
  96       */
  97      protected function loadResourceForBlockName($cacheKey, FormView $view, $blockName)
  98      {
  99          // The caller guarantees that $this->resources[$cacheKey][$block] is
 100          // not set, but it doesn't have to check whether $this->resources[$cacheKey]
 101          // is set. If $this->resources[$cacheKey] is set, all themes for this
 102          // $cacheKey are already loaded (due to the eager population, see doc comment).
 103          if (isset($this->resources[$cacheKey])) {
 104              // As said in the previous, the caller guarantees that
 105              // $this->resources[$cacheKey][$block] is not set. Since the themes are
 106              // already loaded, it can only be a non-existing block.
 107              $this->resources[$cacheKey][$blockName] = false;
 108  
 109              return false;
 110          }
 111  
 112          // Recursively try to find the block in the themes assigned to $view,
 113          // then of its parent view, then of the parent view of the parent and so on.
 114          // When the root view is reached in this recursion, also the default
 115          // themes are taken into account.
 116  
 117          // Check each theme whether it contains the searched block
 118          if (isset($this->themes[$cacheKey])) {
 119              for ($i = \count($this->themes[$cacheKey]) - 1; $i >= 0; --$i) {
 120                  $this->loadResourcesFromTheme($cacheKey, $this->themes[$cacheKey][$i]);
 121                  // CONTINUE LOADING (see doc comment)
 122              }
 123          }
 124  
 125          // Check the default themes once we reach the root view without success
 126          if (!$view->parent) {
 127              if (!isset($this->useDefaultThemes[$cacheKey]) || $this->useDefaultThemes[$cacheKey]) {
 128                  for ($i = \count($this->defaultThemes) - 1; $i >= 0; --$i) {
 129                      $this->loadResourcesFromTheme($cacheKey, $this->defaultThemes[$i]);
 130                      // CONTINUE LOADING (see doc comment)
 131                  }
 132              }
 133          }
 134  
 135          // Proceed with the themes of the parent view
 136          if ($view->parent) {
 137              $parentCacheKey = $view->parent->vars[self::CACHE_KEY_VAR];
 138  
 139              if (!isset($this->resources[$parentCacheKey])) {
 140                  $this->loadResourceForBlockName($parentCacheKey, $view->parent, $blockName);
 141              }
 142  
 143              // EAGER CACHE POPULATION (see doc comment)
 144              foreach ($this->resources[$parentCacheKey] as $nestedBlockName => $resource) {
 145                  if (!isset($this->resources[$cacheKey][$nestedBlockName])) {
 146                      $this->resources[$cacheKey][$nestedBlockName] = $resource;
 147                  }
 148              }
 149          }
 150  
 151          // Even though we loaded the themes, it can happen that none of them
 152          // contains the searched block
 153          if (!isset($this->resources[$cacheKey][$blockName])) {
 154              // Cache that we didn't find anything to speed up further accesses
 155              $this->resources[$cacheKey][$blockName] = false;
 156          }
 157  
 158          return false !== $this->resources[$cacheKey][$blockName];
 159      }
 160  
 161      /**
 162       * Loads the resources for all blocks in a theme.
 163       *
 164       * @param string $cacheKey The cache key for storing the resource
 165       * @param mixed  $theme    The theme to load the block from. This parameter
 166       *                         is passed by reference, because it might be necessary
 167       *                         to initialize the theme first. Any changes made to
 168       *                         this variable will be kept and be available upon
 169       *                         further calls to this method using the same theme.
 170       */
 171      protected function loadResourcesFromTheme($cacheKey, &$theme)
 172      {
 173          if (!$theme instanceof Template) {
 174              /* @var Template $theme */
 175              $theme = $this->environment->loadTemplate($theme);
 176          }
 177  
 178          if (null === $this->template) {
 179              // Store the first Template instance that we find so that
 180              // we can call displayBlock() later on. It doesn't matter *which*
 181              // template we use for that, since we pass the used blocks manually
 182              // anyway.
 183              $this->template = $theme;
 184          }
 185  
 186          // Use a separate variable for the inheritance traversal, because
 187          // theme is a reference and we don't want to change it.
 188          $currentTheme = $theme;
 189  
 190          $context = $this->environment->mergeGlobals([]);
 191  
 192          // The do loop takes care of template inheritance.
 193          // Add blocks from all templates in the inheritance tree, but avoid
 194          // overriding blocks already set.
 195          do {
 196              foreach ($currentTheme->getBlocks() as $block => $blockData) {
 197                  if (!isset($this->resources[$cacheKey][$block])) {
 198                      // The resource given back is the key to the bucket that
 199                      // contains this block.
 200                      $this->resources[$cacheKey][$block] = $blockData;
 201                  }
 202              }
 203          } while (false !== $currentTheme = $currentTheme->getParent($context));
 204      }
 205  }


Generated: Wed Nov 11 20:28:18 2020 Cross-referenced by PHPXref 0.7.1