[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |