[Form] Fixed consideration of Twig's template inheritance and added another performance-improving check

This commit is contained in:
Bernhard Schussek 2012-07-17 09:00:22 +02:00
parent b4ec7f54eb
commit 1474aa5fa2
2 changed files with 37 additions and 10 deletions

View File

@ -78,6 +78,19 @@ class TwigRendererEngine extends AbstractRendererEngine implements TwigRendererE
*/ */
protected function loadResourceForBlock($cacheKey, FormViewInterface $view, $block) protected function loadResourceForBlock($cacheKey, FormViewInterface $view, $block)
{ {
// The caller guarantees that $this->resources[$cacheKey][$block] is
// not set, but it doesn't have to check whether $this->resources[$cacheKey]
// is set. If $this->resources[$cacheKey] is set, all themes for this
// $cacheKey are already loaded (due to the eager population, see doc comment).
if (isset($this->resources[$cacheKey])) {
// As said in the previous, the caller guarantees that
// $this->resources[$cacheKey][$block] is not set. Since the themes are
// already loaded, it can only be a non-existing block.
$this->resources[$cacheKey][$block] = false;
return false;
}
// Recursively try to find the block in the themes assigned to $view, // Recursively try to find the block in the themes assigned to $view,
// then of its parent view, then of the parent view of the parent and so on. // then of its parent view, then of the parent view of the parent and so on.
// When the root view is reached in this recursion, also the default // When the root view is reached in this recursion, also the default
@ -99,8 +112,7 @@ class TwigRendererEngine extends AbstractRendererEngine implements TwigRendererE
} }
} }
// If we did not find anything in the themes of the current view, proceed // Proceed with the themes of the parent view
// with the themes of the parent view
if ($view->hasParent()) { if ($view->hasParent()) {
$parentCacheKey = $view->getParent()->getVar(self::CACHE_KEY_VAR); $parentCacheKey = $view->getParent()->getVar(self::CACHE_KEY_VAR);
@ -116,6 +128,8 @@ class TwigRendererEngine extends AbstractRendererEngine implements TwigRendererE
} }
} }
// Even though we loaded the themes, it can happen that none of them
// contains the searched block
if (!isset($this->resources[$cacheKey][$block])) { if (!isset($this->resources[$cacheKey][$block])) {
// Cache that we didn't find anything to speed up further accesses // Cache that we didn't find anything to speed up further accesses
$this->resources[$cacheKey][$block] = false; $this->resources[$cacheKey][$block] = false;
@ -149,12 +163,21 @@ class TwigRendererEngine extends AbstractRendererEngine implements TwigRendererE
$this->template = $theme; $this->template = $theme;
} }
foreach ($theme->getBlocks() as $block => $blockData) { // Use a separate variable for the inheritance traversal, because
if (!isset($this->resources[$cacheKey][$block])) { // theme is a reference and we don't want to change it.
// The resource given back is the key to the bucket that $currentTheme = $theme;
// contains this block.
$this->resources[$cacheKey][$block] = $blockData; // The do loop takes care of template inheritance.
// Add blocks from all templates in the inheritance tree, but avoid
// overriding blocks already set.
do {
foreach ($currentTheme->getBlocks() as $block => $blockData) {
if (!isset($this->resources[$cacheKey][$block])) {
// The resource given back is the key to the bucket that
// contains this block.
$this->resources[$cacheKey][$block] = $blockData;
}
} }
} } while (false !== $currentTheme = $currentTheme->getParent(array()));
} }
} }

View File

@ -63,8 +63,12 @@ abstract class AbstractRendererEngine implements FormRendererEngineInterface
// Do not cast, as casting turns objects into arrays of properties // Do not cast, as casting turns objects into arrays of properties
$this->themes[$cacheKey] = is_array($themes) ? $themes : array($themes); $this->themes[$cacheKey] = is_array($themes) ? $themes : array($themes);
$this->resources[$cacheKey] = array();
$this->resourceHierarchyLevels[$cacheKey] = array(); // Unset instead of resetting to an empty array, in order to allow
// implementations (like TwigRendererEngine) to check whether $cacheKey
// is set at all.
unset($this->resources[$cacheKey]);
unset($this->resourceHierarchyLevels[$cacheKey]);
} }
/** /**