diff --git a/TODO.txt b/TODO.txt index d01b2fdf..6ca51bcd 100644 --- a/TODO.txt +++ b/TODO.txt @@ -2,21 +2,16 @@ ## Review direct variable property access - review ->value{$index} in ForTag -- review ->(step|total|first|last|do_else|key|show|iteration|index) -- review ->tpl_vars, ->config_vars, ->value +## include inline - Re-introduce merge_compiled_includes and the {include inline} attribute? ## Output buffering - Fix ob_ output buffering commands being scattered around the codebase - ## Review public static vars - such as _CHARSET and _IS_WINDOWS -## Build -- add compiled lexers and parsers to Release assets automatically - ## Benchmark - benchmark to see that performance hasn't degraded @@ -24,7 +19,6 @@ - Consider phasing out $smarty.block.child as this reverses the inheritance hierarchy and might cause infinite loops when combined with $smarty.block.parent - ## Plugin system - fix template security checks in one place in compiler @@ -35,16 +29,6 @@ - beautify and review docs, possibly using [ Material for MkDocs ](https://squidfunk.github.io/mkdocs-material/publishing-your-site/) -## Resources -- Fix circular deps between resources and sources -``` - $smarty = $this->_getSmartyObj(); - [$name, $type] = \Smarty\Resource\BasePlugin::parseResourceName($config_file, $smarty->default_config_type); - $source = new Config($smarty, $config_file, $type, $name); - - $source->handler->getContent($source); -``` - ## Unrelated / other - review (and avoid) use of 'clone' keyword - compiler->has_code seems silly. Why not have proper return values? diff --git a/src/Cacheresource/File.php b/src/Cacheresource/File.php index 54070013..9bd2c778 100644 --- a/src/Cacheresource/File.php +++ b/src/Cacheresource/File.php @@ -205,7 +205,7 @@ class File extends Base if (isset($resource_name)) { $_save_stat = $smarty->caching; $smarty->caching = \Smarty\Smarty::CACHING_LIFETIME_CURRENT; - $tpl = new \Smarty\Template($resource_name, $smarty); + $tpl = $smarty->createTemplate($resource_name); $smarty->caching = $_save_stat; // remove from template cache if ($tpl->getSource()->exists) { diff --git a/src/Data.php b/src/Data.php index cd4fa3e7..5385f694 100644 --- a/src/Data.php +++ b/src/Data.php @@ -454,8 +454,7 @@ class Data */ public function configLoad($config_file, $sections = null) { - $smarty = $this->getSmarty(); - $template = new Template($config_file, $smarty, $this, null, null, null, true); + $template = $this->getSmarty()->createTemplate($config_file, null, null, $this, null, null, null, true); $template->caching = Smarty::CACHING_OFF; $template->assign('sections', (array) $sections ?? []); // trigger a call to $this->assignConfigVars @@ -480,4 +479,18 @@ class Data public function getDefaultScope(): int { return $this->defaultScope; } + + /** + * @return Data|Smarty|null + */ + public function getParent() { + return $this->parent; + } + + /** + * @param Data|Smarty|null $parent + */ + public function setParent($parent): void { + $this->parent = $parent; + } } diff --git a/src/Smarty.php b/src/Smarty.php index bdf67ac0..e7d207fe 100644 --- a/src/Smarty.php +++ b/src/Smarty.php @@ -946,24 +946,25 @@ class Smarty extends \Smarty\TemplateBase return $this; } + private $templates = []; + /** - * creates a template object + * Creates a template object * * @param Template|null $template_name - * * @param mixed $cache_id cache id to be used with this template * @param mixed $compile_id compile id to be used with this template * @param null $parent next higher level of Smarty variables - * $cache_lifetime * @param null $caching * @param null $cache_lifetime * @param string|null $baseFilePath + * @param bool $isConfig * * @return Template template object * @throws Exception */ public function createTemplate($template_name, $cache_id = null, $compile_id = null, $parent = null, $caching = null, - $cache_lifetime = null, string $baseFilePath = null) + $cache_lifetime = null, string $baseFilePath = null, bool $isConfig = false) { $data = null; @@ -983,10 +984,21 @@ class Smarty extends \Smarty\TemplateBase if (!$this->_templateDirNormalized) { $this->_normalizeTemplateConfig(false); } + $_templateId = $this->generateUniqueTemplateId($template_name, $cache_id, $compile_id, $caching, $baseFilePath); - $tpl = new Template($template_name, $this, $parent ?: $this, $cache_id, $compile_id, $caching); - $tpl->templateId = $_templateId; + if (!isset($this->templates[$_templateId])) { + $newTemplate = new Template($template_name, $this, $parent ?: $this, $cache_id, $compile_id, $caching, $isConfig); + $newTemplate->templateId = $_templateId; // @TODO this could go in constructor ^? + $this->templates[$_templateId] = $newTemplate; + } + + $tpl = clone $this->templates[$_templateId]; + + // If $this->allow_ambiguous_resources, the context of the section is different each time + if ($this->allow_ambiguous_resources || $tpl->getParent() !== ($parent ?: $this)) { + $tpl->setParent($parent ?: $this); + } if ($cache_lifetime) { $tpl->setCacheLifetime($cache_lifetime); @@ -1019,7 +1031,7 @@ class Smarty extends \Smarty\TemplateBase * * @return string */ - public function generateUniqueTemplateId( + private function generateUniqueTemplateId( $template_name, $cache_id = null, $compile_id = null, @@ -1573,7 +1585,7 @@ class Smarty extends \Smarty\TemplateBase // $_smarty->force_compile = $force_compile; try { - $_tpl = new \Smarty\Template($_file, $_smarty); + $_tpl = $this->createTemplate($_file); $_tpl->caching = self::CACHING_OFF; $_tpl->setSource( $isConfig ? \Smarty\Template\Config::load($_tpl) : \Smarty\Template\Source::load($_tpl) diff --git a/src/Template.php b/src/Template.php index 43006db5..82a782de 100644 --- a/src/Template.php +++ b/src/Template.php @@ -130,7 +130,8 @@ class Template extends TemplateBase { $this->parent = $_parent; // Template resource $this->template_resource = $template_resource; - $this->source = $_isConfig ? Config::load($this) : Source::load($this); + + $this->setSource($_isConfig ? Config::load($this) : Source::load($this)); if ($smarty->security_policy) { $smarty->security_policy->registerCallBacks($this); @@ -266,12 +267,8 @@ class Template extends TemplateBase { } // recursive call ? - if ($tpl->getTemplateId() !== $this->getTemplateId()) { - $tpl->setSource(Source::load($tpl)); - $tpl->getCompiled(true); - if ($caching !== \Smarty\Template::CACHING_NOCACHE_CODE) { - $tpl->getCached(true); - } + if ($tpl->getTemplateId() !== $this->getTemplateId() && $caching !== \Smarty\Template::CACHING_NOCACHE_CODE) { + $tpl->getCached(true); } if (!empty($extra_vars)) { @@ -289,6 +286,11 @@ class Template extends TemplateBase { $tpl->render(); } + public function setParent($parent): void { + parent::setParent($parent); + $this->setSource($this->source->isConfig ? Config::load($this) : Source::load($this)); + } + /** * Check if this is a sub template * @@ -349,8 +351,7 @@ class Template extends TemplateBase { * @return string */ public function getTemplateId() { - return $this->templateId ?? $this->templateId = - $this->smarty->generateUniqueTemplateId($this->template_resource, $this->cache_id, $this->compile_id); + return $this->templateId; } /**