[ Index ]

PHP Cross Reference of phpBB-3.2.11-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      /**
  35       * {@inheritdoc}
  36       */
  37      public function setEnvironment(Environment $environment)
  38      {
  39          $this->environment = $environment;
  40      }
  41  
  42      /**
  43       * {@inheritdoc}
  44       */
  45      public function renderBlock(FormView $view, $resource, $blockName, array $variables = array())
  46      {
  47          $cacheKey = $view->vars[self::CACHE_KEY_VAR];
  48  
  49          $context = $this->environment->mergeGlobals($variables);
  50  
  51          ob_start();
  52  
  53          // By contract,This method can only be called after getting the resource
  54          // (which is passed to the method). Getting a resource for the first time
  55          // (with an empty cache) is guaranteed to invoke loadResourcesFromTheme(),
  56          // where the property $template is initialized.
  57  
  58          // We do not call renderBlock here to avoid too many nested level calls
  59          // (XDebug limits the level to 100 by default)
  60          $this->template->displayBlock($blockName, $context, $this->resources[$cacheKey]);
  61  
  62          return ob_get_clean();
  63      }
  64  
  65      /**
  66       * Loads the cache with the resource for a given block name.
  67       *
  68       * This implementation eagerly loads all blocks of the themes assigned to the given view
  69       * and all of its ancestors views. This is necessary, because Twig receives the
  70       * list of blocks later. At that point, all blocks must already be loaded, for the
  71       * case that the function "block()" is used in the Twig template.
  72       *
  73       * @see getResourceForBlock()
  74       *
  75       * @param string   $cacheKey  The cache key of the form view
  76       * @param FormView $view      The form view for finding the applying themes
  77       * @param string   $blockName The name of the block to load
  78       *
  79       * @return bool True if the resource could be loaded, false otherwise
  80       */
  81      protected function loadResourceForBlockName($cacheKey, FormView $view, $blockName)
  82      {
  83          // The caller guarantees that $this->resources[$cacheKey][$block] is
  84          // not set, but it doesn't have to check whether $this->resources[$cacheKey]
  85          // is set. If $this->resources[$cacheKey] is set, all themes for this
  86          // $cacheKey are already loaded (due to the eager population, see doc comment).
  87          if (isset($this->resources[$cacheKey])) {
  88              // As said in the previous, the caller guarantees that
  89              // $this->resources[$cacheKey][$block] is not set. Since the themes are
  90              // already loaded, it can only be a non-existing block.
  91              $this->resources[$cacheKey][$blockName] = false;
  92  
  93              return false;
  94          }
  95  
  96          // Recursively try to find the block in the themes assigned to $view,
  97          // then of its parent view, then of the parent view of the parent and so on.
  98          // When the root view is reached in this recursion, also the default
  99          // themes are taken into account.
 100  
 101          // Check each theme whether it contains the searched block
 102          if (isset($this->themes[$cacheKey])) {
 103              for ($i = \count($this->themes[$cacheKey]) - 1; $i >= 0; --$i) {
 104                  $this->loadResourcesFromTheme($cacheKey, $this->themes[$cacheKey][$i]);
 105                  // CONTINUE LOADING (see doc comment)
 106              }
 107          }
 108  
 109          // Check the default themes once we reach the root view without success
 110          if (!$view->parent) {
 111              for ($i = \count($this->defaultThemes) - 1; $i >= 0; --$i) {
 112                  $this->loadResourcesFromTheme($cacheKey, $this->defaultThemes[$i]);
 113                  // CONTINUE LOADING (see doc comment)
 114              }
 115          }
 116  
 117          // Proceed with the themes of the parent view
 118          if ($view->parent) {
 119              $parentCacheKey = $view->parent->vars[self::CACHE_KEY_VAR];
 120  
 121              if (!isset($this->resources[$parentCacheKey])) {
 122                  $this->loadResourceForBlockName($parentCacheKey, $view->parent, $blockName);
 123              }
 124  
 125              // EAGER CACHE POPULATION (see doc comment)
 126              foreach ($this->resources[$parentCacheKey] as $nestedBlockName => $resource) {
 127                  if (!isset($this->resources[$cacheKey][$nestedBlockName])) {
 128                      $this->resources[$cacheKey][$nestedBlockName] = $resource;
 129                  }
 130              }
 131          }
 132  
 133          // Even though we loaded the themes, it can happen that none of them
 134          // contains the searched block
 135          if (!isset($this->resources[$cacheKey][$blockName])) {
 136              // Cache that we didn't find anything to speed up further accesses
 137              $this->resources[$cacheKey][$blockName] = false;
 138          }
 139  
 140          return false !== $this->resources[$cacheKey][$blockName];
 141      }
 142  
 143      /**
 144       * Loads the resources for all blocks in a theme.
 145       *
 146       * @param string $cacheKey The cache key for storing the resource
 147       * @param mixed  $theme    The theme to load the block from. This parameter
 148       *                         is passed by reference, because it might be necessary
 149       *                         to initialize the theme first. Any changes made to
 150       *                         this variable will be kept and be available upon
 151       *                         further calls to this method using the same theme.
 152       */
 153      protected function loadResourcesFromTheme($cacheKey, &$theme)
 154      {
 155          if (!$theme instanceof Template) {
 156              /* @var Template $theme */
 157              $theme = $this->environment->loadTemplate($theme);
 158          }
 159  
 160          if (null === $this->template) {
 161              // Store the first Template instance that we find so that
 162              // we can call displayBlock() later on. It doesn't matter *which*
 163              // template we use for that, since we pass the used blocks manually
 164              // anyway.
 165              $this->template = $theme;
 166          }
 167  
 168          // Use a separate variable for the inheritance traversal, because
 169          // theme is a reference and we don't want to change it.
 170          $currentTheme = $theme;
 171  
 172          $context = $this->environment->mergeGlobals(array());
 173  
 174          // The do loop takes care of template inheritance.
 175          // Add blocks from all templates in the inheritance tree, but avoid
 176          // overriding blocks already set.
 177          do {
 178              foreach ($currentTheme->getBlocks() as $block => $blockData) {
 179                  if (!isset($this->resources[$cacheKey][$block])) {
 180                      // The resource given back is the key to the bucket that
 181                      // contains this block.
 182                      $this->resources[$cacheKey][$block] = $blockData;
 183                  }
 184              }
 185          } while (false !== $currentTheme = $currentTheme->getParent($context));
 186      }
 187  }


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1