[Form] Implemented a more intelligent caching strategy in FormHelper (PHP +100ms, Twig +100ms)
This commit is contained in:
parent
151b79a6ce
commit
216c539e41
|
@ -12,8 +12,8 @@
|
|||
namespace Symfony\Bundle\FrameworkBundle\Templating\Helper;
|
||||
|
||||
use Symfony\Component\Templating\Helper\Helper;
|
||||
use Symfony\Component\Form\FormViewInterface;
|
||||
use Symfony\Component\Templating\EngineInterface;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\Form\Exception\FormException;
|
||||
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
|
||||
use Symfony\Component\Form\Extension\Core\View\ChoiceView;
|
||||
|
@ -27,36 +27,68 @@ use Symfony\Component\Form\Util\FormUtil;
|
|||
*/
|
||||
class FormHelper extends Helper
|
||||
{
|
||||
protected $engine;
|
||||
/**
|
||||
* @var EngineInterface
|
||||
*/
|
||||
private $engine;
|
||||
|
||||
protected $csrfProvider;
|
||||
/**
|
||||
* @var CsrfProviderInterface
|
||||
*/
|
||||
private $csrfProvider;
|
||||
|
||||
protected $varStack;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $blockHierarchyMap = array();
|
||||
|
||||
protected $context;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $currentHierarchyLevelMap = array();
|
||||
|
||||
protected $resources;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $variableMap = array();
|
||||
|
||||
protected $themes;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $stack = array();
|
||||
|
||||
protected $templates;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $defaultThemes;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $themes = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $templateCache = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $templateHierarchyLevelCache = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param EngineInterface $engine The templating engine
|
||||
* @param CsrfProviderInterface $csrfProvider The CSRF provider
|
||||
* @param array $resources An array of theme names
|
||||
* @param array $defaultThemes An array of theme names
|
||||
*/
|
||||
public function __construct(EngineInterface $engine, CsrfProviderInterface $csrfProvider = null, array $resources = array())
|
||||
public function __construct(EngineInterface $engine, CsrfProviderInterface $csrfProvider = null, array $defaultThemes = array())
|
||||
{
|
||||
$this->engine = $engine;
|
||||
$this->csrfProvider = $csrfProvider;
|
||||
$this->resources = $resources;
|
||||
$this->varStack = array();
|
||||
$this->context = array();
|
||||
$this->templates = array();
|
||||
$this->themes = array();
|
||||
$this->defaultThemes = $defaultThemes;
|
||||
}
|
||||
|
||||
public function isChoiceGroup($label)
|
||||
|
@ -64,7 +96,7 @@ class FormHelper extends Helper
|
|||
return FormUtil::isChoiceGroup($label);
|
||||
}
|
||||
|
||||
public function isChoiceSelected(FormView $view, ChoiceView $choice)
|
||||
public function isChoiceSelected(FormViewInterface $view, ChoiceView $choice)
|
||||
{
|
||||
return FormUtil::isChoiceSelected($choice->getValue(), $view->getVar('value'));
|
||||
}
|
||||
|
@ -74,13 +106,14 @@ class FormHelper extends Helper
|
|||
*
|
||||
* The theme format is "<Bundle>:<Controller>".
|
||||
*
|
||||
* @param FormView $view A FormView instance
|
||||
* @param FormViewInterface $view A FormViewInterface instance
|
||||
* @param string|array $themes A theme or an array of theme
|
||||
*/
|
||||
public function setTheme(FormView $view, $themes)
|
||||
public function setTheme(FormViewInterface $view, $themes)
|
||||
{
|
||||
$this->themes[$view->getVar('id')] = (array) $themes;
|
||||
$this->templates = array();
|
||||
$this->themes[$view->getVar('full_block_name')] = (array) $themes;
|
||||
$this->templateCache = array();
|
||||
$this->templateHierarchyLevelCache = array();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -90,11 +123,11 @@ class FormHelper extends Helper
|
|||
*
|
||||
* <form action="..." method="post" <?php echo $view['form']->enctype() ?>>
|
||||
*
|
||||
* @param FormView $view The view for which to render the encoding type
|
||||
* @param FormViewInterface $view The view for which to render the encoding type
|
||||
*
|
||||
* @return string The html markup
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function enctype(FormView $view)
|
||||
public function enctype(FormViewInterface $view)
|
||||
{
|
||||
return $this->renderSection($view, 'enctype');
|
||||
}
|
||||
|
@ -112,12 +145,12 @@ class FormHelper extends Helper
|
|||
*
|
||||
* <?php echo view['form']->widget(array('separator' => '+++++)) ?>
|
||||
*
|
||||
* @param FormView $view The view for which to render the widget
|
||||
* @param FormViewInterface $view The view for which to render the widget
|
||||
* @param array $variables Additional variables passed to the template
|
||||
*
|
||||
* @return string The html markup
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function widget(FormView $view, array $variables = array())
|
||||
public function widget(FormViewInterface $view, array $variables = array())
|
||||
{
|
||||
return $this->renderSection($view, 'widget', $variables);
|
||||
}
|
||||
|
@ -125,12 +158,12 @@ class FormHelper extends Helper
|
|||
/**
|
||||
* Renders the entire form field "row".
|
||||
*
|
||||
* @param FormView $view The view for which to render the row
|
||||
* @param FormViewInterface $view The view for which to render the row
|
||||
* @param array $variables Additional variables passed to the template
|
||||
*
|
||||
* @return string The html markup
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function row(FormView $view, array $variables = array())
|
||||
public function row(FormViewInterface $view, array $variables = array())
|
||||
{
|
||||
return $this->renderSection($view, 'row', $variables);
|
||||
}
|
||||
|
@ -138,13 +171,13 @@ class FormHelper extends Helper
|
|||
/**
|
||||
* Renders the label of the given view.
|
||||
*
|
||||
* @param FormView $view The view for which to render the label
|
||||
* @param FormViewInterface $view The view for which to render the label
|
||||
* @param string $label The label
|
||||
* @param array $variables Additional variables passed to the template
|
||||
*
|
||||
* @return string The html markup
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function label(FormView $view, $label = null, array $variables = array())
|
||||
public function label(FormViewInterface $view, $label = null, array $variables = array())
|
||||
{
|
||||
if ($label !== null) {
|
||||
$variables += array('label' => $label);
|
||||
|
@ -156,11 +189,11 @@ class FormHelper extends Helper
|
|||
/**
|
||||
* Renders the errors of the given view.
|
||||
*
|
||||
* @param FormView $view The view to render the errors for
|
||||
* @param FormViewInterface $view The view to render the errors for
|
||||
*
|
||||
* @return string The html markup
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function errors(FormView $view)
|
||||
public function errors(FormViewInterface $view)
|
||||
{
|
||||
return $this->renderSection($view, 'errors');
|
||||
}
|
||||
|
@ -168,12 +201,12 @@ class FormHelper extends Helper
|
|||
/**
|
||||
* Renders views which have not already been rendered.
|
||||
*
|
||||
* @param FormView $view The parent view
|
||||
* @param FormViewInterface $view The parent view
|
||||
* @param array $variables An array of variables
|
||||
*
|
||||
* @return string The html markup
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function rest(FormView $view, array $variables = array())
|
||||
public function rest(FormViewInterface $view, array $variables = array())
|
||||
{
|
||||
return $this->renderSection($view, 'rest', $variables);
|
||||
}
|
||||
|
@ -200,6 +233,8 @@ class FormHelper extends Helper
|
|||
* @param string $intention The intention of the protected action
|
||||
*
|
||||
* @return string A CSRF token
|
||||
*
|
||||
* @throws \BadMethodCallException When no CSRF provider was injected in the constructor.
|
||||
*/
|
||||
public function csrfToken($intention)
|
||||
{
|
||||
|
@ -219,99 +254,154 @@ class FormHelper extends Helper
|
|||
* 3. the type name is recursively replaced by the parent type name until a
|
||||
* corresponding block is found
|
||||
*
|
||||
* @param FormView $view The form view
|
||||
* @param FormViewInterface $view The form view
|
||||
* @param string $section The section to render (i.e. 'row', 'widget', 'label', ...)
|
||||
* @param array $variables Additional variables
|
||||
*
|
||||
* @return string The html markup
|
||||
* @return string The HTML markup
|
||||
*
|
||||
* @throws FormException if no template block exists to render the given section of the view
|
||||
*/
|
||||
protected function renderSection(FormView $view, $section, array $variables = array())
|
||||
protected function renderSection(FormViewInterface $view, $section, array $variables = array())
|
||||
{
|
||||
$mainTemplate = in_array($section, array('row', 'widget'));
|
||||
if ($mainTemplate && $view->isRendered()) {
|
||||
$renderOnlyOnce = in_array($section, array('row', 'widget'));
|
||||
|
||||
if ($renderOnlyOnce && $view->isRendered()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$template = null;
|
||||
// The cache key for storing the variables and types
|
||||
$mapKey = $view->getVar('full_block_name') . '_' . $section;
|
||||
|
||||
$custom = '_'.$view->getVar('id');
|
||||
$rendering = $custom.$section;
|
||||
// In templates, we have to deal with two kinds of block hierarchies:
|
||||
//
|
||||
// +---------+ +---------+
|
||||
// | Theme B | -------> | Theme A |
|
||||
// +---------+ +---------+
|
||||
//
|
||||
// form_widget -------> form_widget
|
||||
// ^
|
||||
// |
|
||||
// choice_widget -----> choice_widget
|
||||
//
|
||||
// The first kind of hierarchy is the theme hierarchy. This allows to
|
||||
// override the block "choice_widget" from Theme A in the extending
|
||||
// Theme B. This kind of inheritance needs to be supported by the
|
||||
// template engine and, for example, offers "parent()" or similar
|
||||
// functions to fall back from the custom to the parent implementation.
|
||||
//
|
||||
// The second kind of hierarchy is the form type hierarchy. This allows
|
||||
// to implement a custom "choice_widget" block (no matter in which theme),
|
||||
// or to fallback to the block of the parent type, which would be
|
||||
// "form_widget" in this example (again, no matter in which theme).
|
||||
// If the designer wants to explicitely fallback to "form_widget" in his
|
||||
// custom "choice_widget", for example because he only wants to wrap
|
||||
// a <div> around the original implementation, he can simply call the
|
||||
// widget() function again to render the block for the parent type.
|
||||
//
|
||||
// The second kind is implemented in the following blocks.
|
||||
if (!isset($this->blockHierarchyMap[$mapKey])) {
|
||||
// INITIAL CALL
|
||||
// Calculate the hierarchy of template blocks and start on
|
||||
// the bottom level of the hierarchy (= "_<id>_<section>" block)
|
||||
$blockHierarchy = array_map(function ($type) use ($section) {
|
||||
return $type . '_' . $section;
|
||||
}, $view->getVar('types'));
|
||||
$blockHierarchy[] = $view->getVar('full_block_name') . '_' . $section;
|
||||
$currentHierarchyLevel = count($blockHierarchy) - 1;
|
||||
|
||||
if (isset($this->varStack[$rendering])) {
|
||||
$typeIndex = $this->varStack[$rendering]['typeIndex'] - 1;
|
||||
$types = $this->varStack[$rendering]['types'];
|
||||
$variables = array_replace_recursive($this->varStack[$rendering]['variables'], $variables);
|
||||
} else {
|
||||
$types = $view->getVar('types');
|
||||
$types[] = $view->getVar('full_block_name');
|
||||
$typeIndex = count($types) - 1;
|
||||
// The default variable scope contains all view variables, merged with
|
||||
// the variables passed explicitely to the helper
|
||||
$variables = array_replace_recursive($view->getVars(), $variables);
|
||||
$this->varStack[$rendering]['types'] = $types;
|
||||
} else {
|
||||
// RECURSIVE CALL
|
||||
// If a block recursively calls renderSection() again, resume rendering
|
||||
// using the parent type in the hierarchy.
|
||||
$blockHierarchy = $this->blockHierarchyMap[$mapKey];
|
||||
$currentHierarchyLevel = $this->currentHierarchyLevelMap[$mapKey] - 1;
|
||||
|
||||
// Reuse the current scope and merge it with the explicitely passed variables
|
||||
$variables = array_replace_recursive($this->variableMap[$mapKey], $variables);
|
||||
}
|
||||
|
||||
$this->varStack[$rendering]['variables'] = $variables;
|
||||
$cacheKey = $view->getVar('full_block_name');
|
||||
$block = $blockHierarchy[$currentHierarchyLevel];
|
||||
|
||||
do {
|
||||
$types[$typeIndex] .= '_'.$section;
|
||||
$template = $this->lookupTemplate($view, $types[$typeIndex]);
|
||||
// Populate the cache if the template for the block is not known yet
|
||||
if (!isset($this->templateCache[$cacheKey][$block])) {
|
||||
$this->loadTemplateForBlockHierarchy($view, $blockHierarchy, $currentHierarchyLevel);
|
||||
}
|
||||
|
||||
if ($template) {
|
||||
// Escape if no template exists for this block
|
||||
if (!$this->templateCache[$cacheKey][$block]) {
|
||||
throw new FormException(sprintf(
|
||||
'Unable to render the form as none of the following blocks exist: "%s".',
|
||||
implode('", "', array_reverse($blockHierarchy))
|
||||
));
|
||||
}
|
||||
|
||||
$this->varStack[$rendering]['typeIndex'] = $typeIndex;
|
||||
// If $block was previously rendered manually with renderBlock(), the template
|
||||
// is cached but the hierarchy level is not. In this case, we know that the block
|
||||
// exists at this very hierarchy level (renderBlock() does not traverse the hierarchy)
|
||||
// so we can just set it.
|
||||
if (!isset($this->templateHierarchyLevelCache[$cacheKey][$block])) {
|
||||
$this->templateHierarchyLevelCache[$cacheKey][$block] = $currentHierarchyLevel;
|
||||
}
|
||||
|
||||
$this->context[] = array(
|
||||
'variables' => $variables,
|
||||
'view' => $view,
|
||||
);
|
||||
// In order to make recursive calls possible, we need to store the block hierarchy,
|
||||
// the current level of the hierarchy and the variables so that this method can
|
||||
// resume rendering one level higher of the hierarchy when it is called recursively.
|
||||
//
|
||||
// We need to store these values in maps (associative arrays) because within a
|
||||
// call to widget() another call to widget() can be made, but for a different view
|
||||
// object. These nested calls should not override each other.
|
||||
$this->blockHierarchyMap[$mapKey] = $blockHierarchy;
|
||||
$this->currentHierarchyLevelMap[$mapKey] = $this->templateHierarchyLevelCache[$cacheKey][$block];
|
||||
$this->variableMap[$mapKey] = $variables;
|
||||
|
||||
$html = $this->engine->render($template, $variables);
|
||||
// We also need to store the view and the variables so that we can render custom
|
||||
// blocks with renderBlock() using the same themes and variables as in the outer
|
||||
// block.
|
||||
//
|
||||
// A stack is sufficient for this purpose, because renderBlock() always accesses
|
||||
// the immediate next outer scope, which is always stored at the end of the stack.
|
||||
$this->stack[] = array($view, $variables);
|
||||
|
||||
array_pop($this->context);
|
||||
unset($this->varStack[$rendering]);
|
||||
// Do the rendering
|
||||
$html = $this->engine->render($this->templateCache[$cacheKey][$block], $variables);
|
||||
|
||||
if ($mainTemplate) {
|
||||
// Clear the stack
|
||||
array_pop($this->stack);
|
||||
|
||||
// Clear the maps
|
||||
unset($this->blockHierarchyMap[$mapKey]);
|
||||
unset($this->currentHierarchyLevelMap[$mapKey]);
|
||||
unset($this->variableMap[$mapKey]);
|
||||
|
||||
if ($renderOnlyOnce) {
|
||||
$view->setRendered();
|
||||
}
|
||||
|
||||
return trim($html);
|
||||
}
|
||||
} while (--$typeIndex >= 0);
|
||||
|
||||
throw new FormException(sprintf(
|
||||
'Unable to render the form as none of the following blocks exist: "%s".',
|
||||
implode('", "', array_reverse($types))
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a block from a form element.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $variables Additional variables (those would override the current context)
|
||||
*
|
||||
* @throws FormException if the block is not found
|
||||
* @throws FormException if the method is called out of a form element (no context)
|
||||
*/
|
||||
public function renderBlock($name, $variables = array())
|
||||
public function renderBlock($block, $variables = array())
|
||||
{
|
||||
if (0 == count($this->context)) {
|
||||
throw new FormException(sprintf('This method should only be called while rendering a form element.', $name));
|
||||
if (0 == count($this->stack)) {
|
||||
throw new FormException('This method should only be called while rendering a form element.');
|
||||
}
|
||||
|
||||
$context = end($this->context);
|
||||
list($view, $scopeVariables) = end($this->stack);
|
||||
|
||||
$template = $this->lookupTemplate($context['view'], $name);
|
||||
$cacheKey = $view->getVar('full_block_name');
|
||||
|
||||
if (false === $template) {
|
||||
throw new FormException(sprintf('No block "%s" found while rendering the form.', $name));
|
||||
if (!isset($this->templateCache[$cacheKey][$block]) && !$this->loadTemplateForBlock($view, $block)) {
|
||||
throw new FormException(sprintf('No block "%s" found while rendering the form.', $block));
|
||||
}
|
||||
|
||||
$variables = array_replace_recursive($context['variables'], $variables);
|
||||
$variables = array_replace_recursive($scopeVariables, $variables);
|
||||
|
||||
return trim($this->engine->render($template, $variables));
|
||||
return trim($this->engine->render($this->templateCache[$cacheKey][$block], $variables));
|
||||
}
|
||||
|
||||
public function humanize($text)
|
||||
|
@ -325,41 +415,127 @@ class FormHelper extends Helper
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the template to use to render the block
|
||||
* Loads the cache with the template for a specific level of a block hierarchy.
|
||||
*
|
||||
* @param FormView $view The form view
|
||||
* @param string $block The name of the block
|
||||
* For example, the block hierarchy could be:
|
||||
*
|
||||
* @return string|Boolean The template logical name or false when no template is found
|
||||
* <code>
|
||||
* form_widget
|
||||
* choice_widget
|
||||
* entity_widget
|
||||
* </code
|
||||
*
|
||||
* When loading this hierarchy at index 1, the method first tries to find the
|
||||
* block "choice_widget" in any of the themes assigned to $view. If nothing is
|
||||
* found, it then continues to look for "form_widget" and so on.
|
||||
*
|
||||
* This method both stores the template name and the level in the hierarchy at
|
||||
* which the template was found in the cache. In the above example, if the
|
||||
* template "MyBundle:choice_widget.html.php" was found at level 1, this template
|
||||
* and the level "1" are stored. The stored level helps to resume rendering
|
||||
* in recursive calls, where the parent block needs to be rendered (here the
|
||||
* block "form_widget" at level 0).
|
||||
*
|
||||
* @param FormViewInterface $view The form view for finding the applying themes.
|
||||
* @param array $blockHierarchy The block hierarchy, with the most specific block name at the end.
|
||||
* @param integer $currentLevel The level in the block hierarchy that should be loaded.
|
||||
*
|
||||
* @return Boolean True if the cache could be populated successfully, false otherwise.
|
||||
*/
|
||||
protected function lookupTemplate(FormView $view, $block)
|
||||
private function loadTemplateForBlockHierarchy(FormViewInterface $view, array $blockHierarchy, $currentLevel)
|
||||
{
|
||||
$file = $block.'.html.php';
|
||||
$id = $view->getVar('id');
|
||||
$cacheKey = $view->getVar('full_block_name');
|
||||
$block = $blockHierarchy[$currentLevel];
|
||||
|
||||
if (!isset($this->templates[$id][$block])) {
|
||||
$template = false;
|
||||
// Try to find a template for that block
|
||||
if ($this->loadTemplateForBlock($view, $block)) {
|
||||
// If loadTemplateForBlock() returns true, it was able to populate the
|
||||
// cache. The only missing thing is to set the hierarchy level at which
|
||||
// the template was found.
|
||||
$this->templateHierarchyLevelCache[$cacheKey][$block] = $currentLevel;
|
||||
|
||||
$themes = $view->hasParent() ? array() : $this->resources;
|
||||
|
||||
if (isset($this->themes[$id])) {
|
||||
$themes = array_merge($themes, $this->themes[$id]);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($currentLevel > 0) {
|
||||
$parentLevel = $currentLevel - 1;
|
||||
$parentBlock = $blockHierarchy[$parentLevel];
|
||||
|
||||
if ($this->loadTemplateForBlockHierarchy($view, $blockHierarchy, $parentLevel)) {
|
||||
// Cache the shortcuts for further accesses
|
||||
$this->templateCache[$cacheKey][$block] = $this->templateCache[$cacheKey][$parentBlock];
|
||||
$this->templateHierarchyLevelCache[$cacheKey][$block] = $this->templateHierarchyLevelCache[$cacheKey][$parentBlock];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache the result for further accesses
|
||||
$this->templateCache[$cacheKey][$block] = false;
|
||||
$this->templateHierarchyLevelCache[$cacheKey][$block] = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the cache with the template for a given block name.
|
||||
*
|
||||
* The template is first searched in all the themes assigned to $view. If nothing
|
||||
* is found, the search is continued in the themes of the parent view. Once arrived
|
||||
* at the root view, if still nothing has been found, the default themes stored
|
||||
* in this class are searched.
|
||||
*
|
||||
* @param FormViewInterface $view The form view for finding the applying themes.
|
||||
* @param string $block The name of the block to load.
|
||||
*
|
||||
* @return Boolean True if the cache could be populated successfully, false otherwise.
|
||||
*/
|
||||
private function loadTemplateForBlock(FormViewInterface $view, $block)
|
||||
{
|
||||
// Recursively try to find the block in the themes assigned to $view,
|
||||
// then of its parent form, then of the parent form of the parent and so on.
|
||||
// When the root form is reached in this recursion, also the default
|
||||
// themes are taken into account.
|
||||
$cacheKey = $view->getVar('full_block_name');
|
||||
|
||||
// Check the default themes once we reach the root form without success
|
||||
$themes = $view->hasParent() ? array() : $this->defaultThemes;
|
||||
|
||||
// Add the themes that have been registered for that specific element
|
||||
if (isset($this->themes[$cacheKey])) {
|
||||
$themes = array_merge($themes, $this->themes[$cacheKey]);
|
||||
}
|
||||
|
||||
// Check each theme whether it contains the searched block
|
||||
for ($i = count($themes) - 1; $i >= 0; --$i) {
|
||||
if ($this->engine->exists($templateName = $themes[$i].':'.$file)) {
|
||||
$template = $templateName;
|
||||
break;
|
||||
if ($this->engine->exists($templateName = $themes[$i] . ':' . $block . '.html.php')) {
|
||||
$this->templateCache[$cacheKey][$block] = $templateName;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (false === $template && $view->hasParent()) {
|
||||
$template = $this->lookupTemplate($view->getParent(), $block);
|
||||
// If we did not find anything in the themes of the current view, proceed
|
||||
// with the themes of the parent view
|
||||
if ($view->hasParent()) {
|
||||
$parentCacheKey = $view->getParent()->getVar('full_block_name');
|
||||
|
||||
if (!isset($this->templateCache[$parentCacheKey][$block])) {
|
||||
$this->loadTemplateForBlock($view->getParent(), $block);
|
||||
}
|
||||
|
||||
$this->templates[$id][$block] = $template;
|
||||
// If a template exists in the parent themes, cache that template name
|
||||
// for the current theme as well to speed up further accesses
|
||||
if ($this->templateCache[$parentCacheKey][$block]) {
|
||||
$this->templateCache[$cacheKey][$block] = $this->templateCache[$parentCacheKey][$block];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->templates[$id][$block];
|
||||
// Cache that we didn't find anything to speed up further accesses
|
||||
$this->templateCache[$cacheKey][$block] = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Reference in New Issue