- optimize block plugin compiler

This commit is contained in:
uwetews
2016-01-02 11:27:44 +01:00
parent 59343127f7
commit 418492b40b
5 changed files with 102 additions and 184 deletions

View File

@@ -1,6 +1,7 @@
 ===== 3.1.30-dev ===== (xx.xx.xx)  ===== 3.1.30-dev ===== (xx.xx.xx)
02.01.2016 02.01.2016
- update scope handling - update scope handling
- optimize block plugin compiler
01.01.2016 01.01.2016
- remove Smarty::$resource_cache_mode property - remove Smarty::$resource_cache_mode property

View File

@@ -121,7 +121,7 @@ class Smarty extends Smarty_Internal_TemplateBase
/** /**
* smarty version * smarty version
*/ */
const SMARTY_VERSION = '3.1.30-dev/16'; const SMARTY_VERSION = '3.1.30-dev/17';
/** /**
* define variable scopes * define variable scopes

View File

@@ -24,6 +24,13 @@ class Smarty_Internal_Compile_Private_Block_Plugin extends Smarty_Internal_Compi
*/ */
public $optional_attributes = array('_any'); public $optional_attributes = array('_any');
/**
* nesting level
*
* @var int
*/
private $nesting = 0;
/** /**
* Compiles code for the execution of block plugin * Compiles code for the execution of block plugin
* *
@@ -35,55 +42,75 @@ class Smarty_Internal_Compile_Private_Block_Plugin extends Smarty_Internal_Compi
* *
* @return string compiled code * @return string compiled code
*/ */
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter, $tag, $function) public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter, $tag, $function = null)
{ {
if (!isset($tag[5]) || substr($tag, - 5) != 'close') { if (!isset($tag[ 5 ]) || substr($tag, - 5) != 'close') {
// opening tag of block plugin // opening tag of block plugin
// check and get attributes // check and get attributes
$_attr = $this->getAttributes($compiler, $args); $_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) { $this->nesting ++;
if ($_attr[ 'nocache' ] === true) {
$compiler->tag_nocache = true; $compiler->tag_nocache = true;
} }
unset($_attr['nocache']); unset($_attr[ 'nocache' ]);
// convert attributes into parameter array string list($callback, $_paramsArray) = $this->setup($compiler, $_attr, $tag, $function);
$_paramsArray = array();
foreach ($_attr as $_key => $_value) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
$_params = 'array(' . implode(",", $_paramsArray) . ')'; $_params = 'array(' . implode(",", $_paramsArray) . ')';
$this->openTag($compiler, $tag, array($_params, $compiler->nocache)); $this->openTag($compiler, $tag, array($_params, $compiler->nocache, $callback));
// maybe nocache because of nocache variables or nocache plugin // maybe nocache because of nocache variables or nocache plugin
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache; $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
// compile code // compile code
$output = "<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>"; $output =
"<?php \$_block_repeat{$this->nesting}=true;\necho {$callback}({$_params}, null, \$_smarty_tpl, \$_block_repeat{$this->nesting});\nwhile (\$_block_repeat{$this->nesting}) {\nob_start();\n?>";
} else { } else {
// must endblock be nocache? // must endblock be nocache?
if ($compiler->nocache) { if ($compiler->nocache) {
$compiler->tag_nocache = true; $compiler->tag_nocache = true;
} }
// closing tag of block plugin, restore nocache // closing tag of block plugin, restore nocache
list($_params, $compiler->nocache) = $this->closeTag($compiler, substr($tag, 0, - 5)); list($_params, $compiler->nocache, $callback) = $this->closeTag($compiler, substr($tag, 0, - 5));
// This tag does create output // This tag does create output
$compiler->has_output = true; $compiler->has_output = true;
// compile code // compile code
if (!isset($parameter['modifier_list'])) { if (!isset($parameter[ 'modifier_list' ])) {
$mod_pre = $mod_post = ''; $mod_pre = $mod_post = $mod_content = '';
$mod_content2 = 'ob_get_clean()';
} else { } else {
$mod_pre = ' ob_start(); '; $mod_content2 = "\$_block_content{$this->nesting}";
$mod_post = 'echo ' . $mod_content = "\$_block_content{$this->nesting} = ob_get_clean();\n";
$compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifier_list'], $mod_pre = "ob_start();\n";
'value' => 'ob_get_clean()')) . ';'; $mod_post = 'echo ' . $compiler->compileTag('private_modifier', array(),
array('modifierlist' => $parameter[ 'modifier_list' ],
'value' => 'ob_get_clean()')) . ";\n";
} }
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre . $output = "<?php " . $mod_content . "\$_block_repeat{$this->nesting}=false;\n" . $mod_pre .
" echo {$function}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " . $mod_post . "echo {$callback}({$_params}, " . $mod_content2 .
" } array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>"; ", \$_smarty_tpl, \$_block_repeat{$this->nesting});\n" . $mod_post . "}\n?>";
$this->nesting --;
} }
return $output . "\n"; return $output . "\n";
} }
/**
* Setup callback and parameter array
*
* @param \Smarty_Internal_TemplateCompilerBase $compiler
* @param array $_attr attributes
* @param string $tag
* @param string $function
*
* @return array
*/
public function setup(Smarty_Internal_TemplateCompilerBase $compiler, $_attr, $tag, $function)
{
$_paramsArray = array();
foreach ($_attr as $_key => $_value) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
return array($function, $_paramsArray);
}
} }

View File

@@ -14,78 +14,29 @@
* @package Smarty * @package Smarty
* @subpackage Compiler * @subpackage Compiler
*/ */
class Smarty_Internal_Compile_Private_Object_Block_Function extends Smarty_Internal_CompileBase class Smarty_Internal_Compile_Private_Object_Block_Function extends Smarty_Internal_Compile_Private_Block_Plugin
{ {
/** /**
* Attribute definition: Overwrites base class. * Setup callback and parameter array
* *
* @var array * @param \Smarty_Internal_TemplateCompilerBase $compiler
* @see Smarty_Internal_CompileBase * @param array $_attr attributes
* @param string $tag
* @param string $method
*
* @return array
*/ */
public $optional_attributes = array('_any'); public function setup(Smarty_Internal_TemplateCompilerBase $compiler, $_attr, $tag, $method)
/**
* Compiles code for the execution of block plugin
*
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
* @param string $tag name of block object
* @param string $method name of method to call
*
* @return string compiled code
*/
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter, $tag, $method)
{ {
if (!isset($tag[5]) || substr($tag, - 5) != 'close') { $_paramsArray = array();
// opening tag of block plugin foreach ($_attr as $_key => $_value) {
// check and get attributes if (is_int($_key)) {
$_attr = $this->getAttributes($compiler, $args); $_paramsArray[] = "$_key=>$_value";
if ($_attr['nocache'] === true) {
$compiler->tag_nocache = true;
}
unset($_attr['nocache']);
// convert attributes into parameter array string
$_paramsArray = array();
foreach ($_attr as $_key => $_value) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
$_params = 'array(' . implode(",", $_paramsArray) . ')';
$this->openTag($compiler, $tag . '->' . $method, array($_params, $compiler->nocache));
// maybe nocache because of nocache variables or nocache plugin
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
// compile code
$output =
"<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}->{$method}', {$_params}); \$_block_repeat=true; echo \$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
} else {
$base_tag = substr($tag, 0, - 5);
// must endblock be nocache?
if ($compiler->nocache) {
$compiler->tag_nocache = true;
}
// closing tag of block plugin, restore nocache
list($_params, $compiler->nocache) = $this->closeTag($compiler, $base_tag . '->' . $method);
// This tag does create output
$compiler->has_output = true;
// compile code
if (!isset($parameter['modifier_list'])) {
$mod_pre = $mod_post = '';
} else { } else {
$mod_pre = ' ob_start(); '; $_paramsArray[] = "'$_key'=>$_value";
$mod_post = 'echo ' . $compiler->compileTag('private_modifier', array(),
array('modifierlist' => $parameter['modifier_list'],
'value' => 'ob_get_clean()')) . ';';
} }
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre .
" echo \$_smarty_tpl->smarty->registered_objects['{$base_tag}'][0]->{$method}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " .
$mod_post . " } array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>";
} }
$callback = "\$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}";
return $output . "\n"; return array($callback, $_paramsArray);
} }
} }

View File

@@ -14,106 +14,45 @@
* @package Smarty * @package Smarty
* @subpackage Compiler * @subpackage Compiler
*/ */
class Smarty_Internal_Compile_Private_Registered_Block extends Smarty_Internal_CompileBase class Smarty_Internal_Compile_Private_Registered_Block extends Smarty_Internal_Compile_Private_Block_Plugin
{ {
/** /**
* Attribute definition: Overwrites base class. * Setup callback, parameter array and nocache mode
* *
* @var array * @param \Smarty_Internal_TemplateCompilerBase $compiler
* @see Smarty_Internal_CompileBase * @param array $_attr attributes
* @param string $tag
* @param null $function
*
* @return array
*/ */
public $optional_attributes = array('_any'); public function setup(Smarty_Internal_TemplateCompilerBase $compiler, $_attr, $tag, $function)
/**
* Compiles code for the execution of a block function
*
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
* @param string $tag name of block function
*
* @return string compiled code
*/
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter, $tag)
{ {
if (!isset($tag[5]) || substr($tag, - 5) != 'close') { if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$tag])) {
// opening tag of block plugin $tag_info = $compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$tag];
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache']) {
$compiler->tag_nocache = true;
}
unset($_attr['nocache']);
if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$tag])) {
$tag_info = $compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$tag];
} else {
$tag_info = $compiler->default_handler_plugins[Smarty::PLUGIN_BLOCK][$tag];
}
// convert attributes into parameter array string
$_paramsArray = array();
foreach ($_attr as $_key => $_value) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} elseif ($compiler->template->caching && in_array($_key, $tag_info[2])) {
$_value = str_replace("'", "^#^", $_value);
$_paramsArray[] = "'$_key'=>^#^.var_export($_value,true).^#^";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
$_params = 'array(' . implode(",", $_paramsArray) . ')';
$this->openTag($compiler, $tag, array($_params, $compiler->nocache));
// maybe nocache because of nocache variables or nocache plugin
$compiler->nocache = !$tag_info[1] | $compiler->nocache | $compiler->tag_nocache;
$function = $tag_info[0];
// compile code
if (!is_array($function)) {
$output = "<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
} elseif (is_object($function[0])) {
$output = "<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}', {$_params}); \$_block_repeat=true; echo \$_smarty_tpl->smarty->registered_plugins['block']['{$tag}'][0][0]->{$function[1]}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
} else {
$output = "<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function[0]}::{$function[1]}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
}
} else { } else {
// must endblock be nocache? $tag_info = $compiler->default_handler_plugins[Smarty::PLUGIN_BLOCK][$tag];
if ($compiler->nocache) { }
$compiler->tag_nocache = true; $compiler->tag_nocache = !$tag_info[ 1 ] | $compiler->tag_nocache;
} $callback = $tag_info[ 0 ];
$base_tag = substr($tag, 0, - 5); if (is_array($callback)) {
// closing tag of block plugin, restore nocache if (is_object($callback[ 0 ])) {
list($_params, $compiler->nocache) = $this->closeTag($compiler, $base_tag); $callback = "\$_smarty_tpl->smarty->registered_plugins['block']['{$tag}'][0][0]->{$callback[1]}";
// This tag does create output
$compiler->has_output = true;
if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$base_tag])) {
$function = $compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$base_tag][0];
} else { } else {
$function = $compiler->default_handler_plugins[Smarty::PLUGIN_BLOCK][$base_tag][0]; $callback = "{$callback[0]}::{$callback[1]}";
}
// compile code
if (!isset($parameter['modifier_list'])) {
$mod_pre = $mod_post = '';
} else {
$mod_pre = ' ob_start(); ';
$mod_post = 'echo ' .
$compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifier_list'],
'value' => 'ob_get_clean()')) . ';';
}
if (!is_array($function)) {
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre .
" echo {$function}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat);" . $mod_post .
" } array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>";
} elseif (is_object($function[0])) {
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre .
" echo \$_smarty_tpl->smarty->registered_plugins['block']['{$base_tag}'][0][0]->{$function[1]}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " .
$mod_post . "} array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>";
} else {
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre .
" echo {$function[0]}::{$function[1]}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " .
$mod_post . "} array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>";
} }
} }
$_paramsArray = array();
return $output . "\n"; foreach ($_attr as $_key => $_value) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} elseif ($compiler->template->caching && in_array($_key, $tag_info[ 2 ])) {
$_value = str_replace("'", "^#^", $_value);
$_paramsArray[] = "'$_key'=>^#^.var_export($_value,true).^#^";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
return array($callback, $_paramsArray);
} }
} }