Implemented the DefaultHandlerBlockCompiler, made the dependencies of the template compiler into properties, fixed a couple of unit tests

This commit is contained in:
Simon Wisselink
2023-01-05 11:18:42 +01:00
parent 2b71415d1f
commit e89a3dda49
8 changed files with 99 additions and 21 deletions

View File

@@ -35,7 +35,7 @@ class BlockCompiler extends Base {
*
* @var int
*/
public $nesting = 0;
private $nesting = 0;
/**

View File

@@ -0,0 +1,21 @@
<?php
namespace Smarty\Compile;
class DefaultHandlerBlockCompiler extends BlockCompiler {
/**
* @inheritDoc
*/
protected function getIsCallableCode($tag, $function): string {
return "\$_smarty_tpl->smarty->getRuntime('DefaultPluginHandler')->hasPlugin(" .
var_export($function, true) . ", 'block')";
}
/**
* @inheritDoc
*/
protected function getFullCallbackCode($tag, $function): string {
return "\$_smarty_tpl->smarty->getRuntime('DefaultPluginHandler')->getCallback(" .
var_export($function, true) . ", 'block')";
}
}

View File

@@ -35,8 +35,8 @@ class DefaultHandlerFunctionCallCompiler extends Base {
$_paramsArray = $this->formatParamsArray($_attr);
$_params = 'array(' . implode(',', $_paramsArray) . ')';
$output = "\$_smarty_tpl->smarty->getRuntime('DefaultPluginHandler')->runPlugin(" . var_export($function, true) .
",'function',$_params, \$_smarty_tpl)";
$output = "\$_smarty_tpl->smarty->getRuntime('DefaultPluginHandler')->getCallback(" . var_export($function, true) .
",'function')($_params, \$_smarty_tpl)";
if (!empty($parameter['modifierlist'])) {
$output = $compiler->compileModifier($parameter['modifierlist'], $output);

View File

@@ -11,6 +11,7 @@
namespace Smarty\Compiler;
use Smarty\Compile\BlockCompiler;
use Smarty\Compile\DefaultHandlerBlockCompiler;
use Smarty\Compile\DefaultHandlerFunctionCallCompiler;
use Smarty\Compile\ModifierCompiler;
use Smarty\Compile\ObjectMethodBlockCompiler;
@@ -290,6 +291,30 @@ class Template extends BaseCompiler {
* @var ObjectMethodBlockCompiler
*/
private $objectMethodBlockCompiler;
/**
* @var DefaultHandlerBlockCompiler
*/
private $defaultHandlerBlockCompiler;
/**
* @var BlockCompiler
*/
private $blockCompiler;
/**
* @var DefaultHandlerFunctionCallCompiler
*/
private $defaultHandlerFunctionCallCompiler;
/**
* @var FunctionCallCompiler
*/
private $functionCallCompiler;
/**
* @var ObjectMethodCallCompiler
*/
private $objectMethodCallCompiler;
/**
* @var ModifierCompiler
*/
private $modifierCompiler;
/**
* Initialize compiler
@@ -307,7 +332,13 @@ class Template extends BaseCompiler {
uniqid(mt_rand(), true)
);
$this->modifierCompiler = new ModifierCompiler();
$this->functionCallCompiler = new FunctionCallCompiler();
$this->defaultHandlerFunctionCallCompiler = new DefaultHandlerFunctionCallCompiler();
$this->blockCompiler = new BlockCompiler();
$this->defaultHandlerBlockCompiler = new DefaultHandlerBlockCompiler();
$this->objectMethodBlockCompiler = new ObjectMethodBlockCompiler();
$this->objectMethodCallCompiler = new ObjectMethodCallCompiler();
}
/**
@@ -461,7 +492,7 @@ class Template extends BaseCompiler {
* @throws Exception
*/
public function compileModifier($modifierlist, $value) {
return (new ModifierCompiler())->compile([], $this, ['modifierlist' => $modifierlist, 'value' => $value]);
return $this->modifierCompiler->compile([], $this, ['modifierlist' => $modifierlist, 'value' => $value]);
}
/**
@@ -1247,21 +1278,19 @@ class Template extends BaseCompiler {
// check if tag is a function
if ($this->smarty->getFunctionHandler($base_tag)) {
if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($base_tag, $this)) {
$compiler = new FunctionCallCompiler();
return $compiler->compile($args, $this, $parameter, $tag, $base_tag);
return $this->functionCallCompiler->compile($args, $this, $parameter, $tag, $base_tag);
}
}
// check if tag is a block
if ($this->smarty->getBlockHandler($base_tag)) {
if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($base_tag, $this)) {
$compiler = new BlockCompiler();
return $compiler->compile($args, $this, $parameter, $tag, $base_tag);
return $this->blockCompiler->compile($args, $this, $parameter, $tag, $base_tag);
}
}
// the default plugin handler is a handler of last resort, it may also handle not specifically registered tags.
if ($callback = $this->getPluginFromDefaultHandler($tag, Smarty::PLUGIN_COMPILER)) {
if ($callback = $this->getPluginFromDefaultHandler($base_tag, Smarty::PLUGIN_COMPILER)) {
$tagCompiler = new \Smarty\Compile\Tag\BCPluginWrapper($callback);
$new_args = [];
foreach ($args as $key => $mixed) {
@@ -1274,14 +1303,12 @@ class Template extends BaseCompiler {
return $tagCompiler->compile($new_args, $this, $parameter);
}
if ($this->getPluginFromDefaultHandler($tag, Smarty::PLUGIN_FUNCTION)) {
$compiler = new DefaultHandlerFunctionCallCompiler();
return $compiler->compile($args, $this, $parameter, $tag, $base_tag);
if ($this->getPluginFromDefaultHandler($base_tag, Smarty::PLUGIN_FUNCTION)) {
return $this->defaultHandlerFunctionCallCompiler->compile($args, $this, $parameter, $tag, $base_tag);
}
if ($this->getPluginFromDefaultHandler($tag, Smarty::PLUGIN_BLOCK)) {
$compiler = new BlockCompiler();
return $compiler->compile($args, $this, $parameter, $tag, $base_tag);
if ($this->getPluginFromDefaultHandler($base_tag, Smarty::PLUGIN_BLOCK)) {
return $this->defaultHandlerBlockCompiler->compile($args, $this, $parameter, $tag, $base_tag);
}
$this->trigger_template_error("unknown tag '{$tag}'", null, true);
@@ -1432,7 +1459,7 @@ class Template extends BaseCompiler {
if ($allowedAsBlockFunction) {
return $this->objectMethodBlockCompiler->compile($args, $this, $parameter, $tag, $method);
} elseif ($allowedAsNormalFunction) {
return (new ObjectMethodCallCompiler())->compile($args, $this, $parameter, $tag, $method);
return $this->objectMethodCallCompiler->compile($args, $this, $parameter, $tag, $method);
}
$this->trigger_template_error(

View File

@@ -15,10 +15,34 @@ class DefaultPluginHandlerRuntime {
$this->defaultPluginHandler = $defaultPluginHandler;
}
public function hasPlugin($tag, $plugin_type): bool {
if ($this->defaultPluginHandler === null) {
return false;
}
$callback = null;
// these are not used here
$script = null;
$cacheable = null;
return (call_user_func_array(
$this->defaultPluginHandler,
[
$tag,
$plugin_type,
null, // This used to pass $this->template, but this parameter has been removed in 5.0
&$callback,
&$script,
&$cacheable,
]
) && $callback);
}
/**
* @throws Exception
*/
public function runPlugin($tag, $plugin_type, $params, \Smarty\Template $template) {
public function getCallback($tag, $plugin_type) {
if ($this->defaultPluginHandler === null) {
return false;
@@ -41,8 +65,9 @@ class DefaultPluginHandlerRuntime {
&$cacheable,
]
) && $callback) {
return $callback($params, $template);
return $callback;
}
throw new Exception("Default plugin handler: Returned callback for '{$tag}' not callable at runtime");
}
}

View File

@@ -429,8 +429,8 @@ function my_block_plugin_handler($tag, $type, $template, &$callback, &$script, &
case \Smarty\Smarty::PLUGIN_BLOCK:
switch ($tag) {
case 'scriptblock':
$script = './scripts/script_block_tag.php';
$callback = 'default_script_block_tag';
$script = './scripts/script_block_tag2.php';
$callback = 'default_script_block_tag2';
return true;
default:

View File

@@ -1,5 +1,5 @@
<?php
function default_script_block_tag($params, $content, $template, &$repeat)
function default_script_block_tag2($params, $content, $template, &$repeat)
{
if (isset($content)) {
return 'scriptblock ' . $content;

View File

@@ -22,6 +22,11 @@ class PluginBlockTextformatTest extends PHPUnit_Smarty
$this->setUpSmarty(__DIR__);
}
public function testInit()
{
$this->cleanDirs();
}
public function testDefault()
{
$result = "This is foo. This is foo. This is foo.\nThis is foo. This is foo. This is foo.\n\nThis is bar.\n\nbar foo bar foo foo. bar foo bar foo\nfoo. bar foo bar foo foo. bar foo bar\nfoo foo. bar foo bar foo foo. bar foo\nbar foo foo. bar foo bar foo foo.\n\n";