- implemented registered resources as in Smarty2. NOTE: caching does not work yet

- new property 'force_cache'. if true it forces the creation of a new cache file
- fixed modifiers on arrays
- some speed optimization on loading internal classes
This commit is contained in:
Uwe.Tews
2009-08-27 14:59:28 +00:00
parent e759f76661
commit 4331452b8e
7 changed files with 216 additions and 47 deletions

View File

@@ -1,3 +1,10 @@
08/24/2009
- implemented registered resources as in Smarty2. NOTE: caching does not work yet
- new property 'force_cache'. if true it forces the creation of a new cache file
- fixed modifiers on arrays
- some speed optimization on loading internal classes
08/24/2009
- fixed typo in lexer definition for '!==' operator
- bugfix - the ouput of plugins was not cached

View File

@@ -102,6 +102,8 @@ class Smarty extends Smarty_Internal_TemplateBase {
public $caching = false;
// caching lifetime
public $caching_lifetime = 0;
// force cache file creation
public $force_cache = false;
// cache_id
public $cache_id = null;
// compile_id
@@ -209,13 +211,14 @@ class Smarty extends Smarty_Internal_TemplateBase {
$this->config_dir = '.' . DIRECTORY_SEPARATOR . 'configs' . DIRECTORY_SEPARATOR;
$this->sysplugins_dir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'sysplugins' . DIRECTORY_SEPARATOR;
$this->debug_tpl = SMARTY_DIR . 'debug.tpl';
// load base plugins
$this->loadPlugin('Smarty_Internal_Base');
$this->loadPlugin('Smarty_Internal_PluginBase');
$this->loadPlugin($this->template_class);
$this->loadPlugin('Smarty_Internal_Plugin_Handler');
// load basic plugins
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'sysplugins' . DIRECTORY_SEPARATOR . 'internal.template.php');
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'sysplugins' . DIRECTORY_SEPARATOR . 'internal.Plugin_Handler.php');
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'sysplugins' . DIRECTORY_SEPARATOR . 'internal.Run_Filter.php');
// $this->loadPlugin($this->template_class);
// $this->loadPlugin('Smarty_Internal_Plugin_Handler');
// $this->loadPlugin('Smarty_Internal_Run_Filter');
$this->plugin_handler = new Smarty_Internal_Plugin_Handler($this);
$this->loadPlugin('Smarty_Internal_Run_Filter');
$this->filter_handler = new Smarty_Internal_Run_Filter($this);
if (!$this->debugging && $this->debugging_ctrl == 'URL') {
if (isset($_SERVER['QUERY_STRING'])) {

View File

@@ -24,13 +24,43 @@ class Smarty_Internal_Plugin_Handler {
public function __call($name, $args)
{
if ($this->loadSmartyPlugin($name, $args[1])) {
// call plugin
// call plugin
return call_user_func_array($this->smarty->registered_plugins[$name][1], $args[0]);
} else {
// plugin not found
throw new Exception("Unable to load plugin {$name}");
}
}
public function executeModifier($name, $args, $check_array)
{
if ($this->loadSmartyPlugin($name, 'modifier')) {
// call plugin
if (!$check_array || !is_array($args[0])) {
return call_user_func_array($this->smarty->registered_plugins[$name][1], $args);
} else {
$args0 = $args[0];
foreach ($args0 as $key => $arg0) {
$args[0] = $arg0;
$result[$key] = call_user_func_array($this->smarty->registered_plugins[$name][1], $args);
}
return $result;
}
} elseif (is_callable($name)) {
if (!$check_array || !is_array($args[0])) {
return call_user_func_array($name, $args);
} else {
$args0 = $args[0];
foreach ($args0 as $key => $arg0) {
$args[0] = $arg0;
$result[$key] = call_user_func_array($name, $args);
}
return $result;
}
} else {
// plugin not found
throw new Exception("Unable to load plugin {$name}");
}
}
/**
* Lazy loads plugin files
* class name format: Smarty_PluginType_FuncName

View File

@@ -0,0 +1,125 @@
<?php
/**
* Smarty Internal Plugin Resource Registered
*
* Implements the registered resource for Smarty template
*
* @package Smarty
* @subpackage TemplateResources
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Resource Registered
*/
class Smarty_Internal_Resource_Registered {
public function __construct($smarty)
{
$this->smarty = $smarty;
}
// classes used for compiling Smarty templates from file resource
public $compiler_class = 'Smarty_Internal_SmartyTemplateCompiler';
public $template_lexer_class = 'Smarty_Internal_Templatelexer';
public $template_parser_class = 'Smarty_Internal_Templateparser';
/**
* Get filepath to template source
*
* @param object $_template template object
* @return string return 'string' as template source is not a file
*/
public function getTemplateFilepath($_template)
{
// no filepath for strings
// return "string" for compiler error messages
$_filepath = $_template->resource_type .':'.$_template->resource_name;
return $_filepath;
}
/**
* Get timestamp to template source
*
* @param object $_template template object
* @return boolean false as string resources have no timestamp
*/
public function getTemplateTimestamp($_template)
{
// return timestamp
$time_stamp = false;
call_user_func_array($this->smarty->_plugins['resource'][$_template->resource_type][0][1],
array($_template->resource_name, &$time_stamp, $this->smarty));
return $time_stamp;
}
/**
* Retuen template source from resource name
*
* @param object $_template template object
* @return string content of template source
*/
public function getTemplateSource($_template)
{
// return template string
return call_user_func_array($this->smarty->_plugins['resource'][$_template->resource_type][0][0],
array($_template->resource_name, &$_template->template_source, $this->smarty));
}
/**
* Return flag that this resource uses the compiler
*
* @return boolean true
*/
public function usesCompiler()
{
// resource string is template, needs compiler
return true;
}
/**
* Return flag that this resource is evaluated
*
* @return boolean true
*/
public function isEvaluated()
{
// compiled template is evaluated instead of saved to disk
return false;
}
/**
* Get filepath to compiled template
*
* @param object $_template template object
* @return boolean return false as compiled template is not stored
*/
public function getCompiledFilepath($_template)
{
// $_filepath = md5($_template->resource_name);
$_filepath = (string)abs(crc32($_template->resource_name));
// if use_sub_dirs, break file into directories
if ($_template->smarty->use_sub_dirs) {
$_filepath = substr($_filepath, 0, 3) . DIRECTORY_SEPARATOR
. substr($_filepath, 0, 2) . DIRECTORY_SEPARATOR
. substr($_filepath, 0, 1) . DIRECTORY_SEPARATOR
. $_filepath;
}
$_compile_dir_sep = $_template->smarty->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
if (isset($_template->compile_id)) {
$_filepath = $_template->compile_id . $_compile_dir_sep . $_filepath;
}
if ($_template->caching) {
$_cache = '.cache';
} else {
$_cache = '';
}
$_compile_dir = $_template->smarty->compile_dir;
if (strpos('/\\', substr($_compile_dir, -1)) === false) {
$_compile_dir .= DIRECTORY_SEPARATOR;
}
return $_compile_dir . $_filepath . '.' . basename($_template->resource_name) . $_cache . '.' . $_template->resource_type . $_template->smarty->php_ext;
}
}
?>

View File

@@ -85,6 +85,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
$this->force_compile = $this->smarty->force_compile;
$this->caching = $this->smarty->caching;
$this->caching_lifetime = $this->smarty->caching_lifetime;
$this->force_cache = $this->smarty->force_cache;
$this->cacher_class = $this->smarty->cacher_class;
$this->caching_type = $this->smarty->default_caching_type;
$this->security = $this->smarty->security;
@@ -154,7 +155,9 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
public function getTemplateSource ()
{
if ($this->template_source === null) {
$this->resource_objects[$this->resource_type]->getTemplateSource($this);
if (!$this->resource_objects[$this->resource_type]->getTemplateSource($this)) {
throw new Exception("Unable to read template '{$this->resource_name}'");
}
}
return $this->template_source;
}
@@ -384,7 +387,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
{
if ($this->isCached === null) {
$this->isCached = false;
if ($this->caching && !$this->isEvaluated() && !$this->force_compile) {
if ($this->caching && !$this->isEvaluated() && !$this->force_compile && !$this->force_cache) {
if ($this->getCachedTimestamp() === false) {
return $this->isCached;
}
@@ -545,31 +548,37 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
}
// load resource handler if required
if (!isset($this->resource_objects[$this->resource_type])) {
// try sysplugins dir first
$_resource_class = "Smarty_Internal_Resource_{$this->resource_type}";
if ($this->smarty->loadPlugin($_resource_class)) {
$this->resource_objects[$this->resource_type] = new $_resource_class($this->smarty);
// try registered resource
if (isset($this->smarty->_plugins['resource'][$this->resource_type])) {
$this->smarty->loadPlugin('Smarty_Internal_Resource_Registered');
$this->resource_objects[$this->resource_type] = new Smarty_Internal_Resource_Registered($this->smarty);
} else {
// try plugins dir
$_resource_class = "Smarty_Resource_{$this->resource_type}";
// try sysplugins dir
$_resource_class = "Smarty_Internal_Resource_{$this->resource_type}";
if ($this->smarty->loadPlugin($_resource_class)) {
$this->resource_objects[$this->resource_type] = new $_resource_class($this->smarty);
} else {
// try streams
$_known_stream = stream_get_wrappers();
if (in_array($this->resource_type, $_known_stream)) {
// is known stream
if ($this->smarty->security) {
$this->smarty->security_handler->isTrustedStream($this->resource_type);
}
if (!isset($this->resource_objects['stream'])) {
$this->smarty->loadPlugin('Smarty_Internal_Resource_Stream');
$this->resource_objects['stream'] = new Smarty_Internal_Resource_Stream($this->smarty);
}
$this->resource_type = 'stream';
$this->resource_name = str_replace(':', '://', $template_resource);
// try plugins dir
$_resource_class = "Smarty_Resource_{$this->resource_type}";
if ($this->smarty->loadPlugin($_resource_class)) {
$this->resource_objects[$this->resource_type] = new $_resource_class($this->smarty);
} else {
throw new Exception('Unkown resource type \'' . $this->resource_type . '\'');
// try streams
$_known_stream = stream_get_wrappers();
if (in_array($this->resource_type, $_known_stream)) {
// is known stream
if ($this->smarty->security) {
$this->smarty->security_handler->isTrustedStream($this->resource_type);
}
if (!isset($this->resource_objects['stream'])) {
$this->smarty->loadPlugin('Smarty_Internal_Resource_Stream');
$this->resource_objects['stream'] = new Smarty_Internal_Resource_Stream($this->smarty);
}
$this->resource_type = 'stream';
$this->resource_name = str_replace(':', '://', $template_resource);
} else {
throw new Exception('Unkown resource type \'' . $this->resource_type . '\'');
}
}
}
}
@@ -577,7 +586,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
// cache template object under a unique ID
// do not cache string resources
if ($this->resource_type != 'string') {
$this->smarty->template_objects[$this->buildTemplateId ($this->template_resource, $this->cache_id, $this->compile_id)] = $this;
$this->smarty->template_objects[$this->buildTemplateId ($this->template_resource, $this->cache_id, $this->compile_id)] = $this;
}
return true;
}
@@ -591,7 +600,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
$file = $this->resource_name;
}
foreach((array)$this->smarty->template_dir as $_template_dir) {
if (strpos('/\\',substr($_template_dir, -1)) === false) {
if (strpos('/\\', substr($_template_dir, -1)) === false) {
$_template_dir .= DIRECTORY_SEPARATOR;
}

View File

@@ -24,11 +24,6 @@ class Smarty_Internal_TemplateCompilerBase {
*/
public function __construct()
{
// get required plugins
if (!is_object($this->smarty->filter_handler) && (isset($this->smarty->autoload_filters['pre']) || isset($this->smarty->registered_filters['pre']) || isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post']))) {
$this->smarty->loadPlugin('Smarty_Internal_Run_Filter');
$this->smarty->filter_handler = new Smarty_Internal_Run_Filter;
}
}
// abstract function doCompile($_content);
/**

View File

@@ -1970,18 +1970,18 @@ static public $yy_action = array(
#line 1975 "internal.templateparser.php"
#line 151 "internal.templateparser.y"
function yy_r18(){ preg_match('/\s*/',$this->yystack[$this->yyidx + -5]->minor,$s); $this->_retvalue = $s[0].'<?php ob_start();?>'.$this->compiler->compileTag($this->yystack[$this->yyidx + -4]->minor,$this->yystack[$this->yyidx + -1]->minor).'<?php echo ';
if ($this->smarty->plugin_handler->loadSmartyPlugin($this->yystack[$this->yyidx + -3]->minor[0],'modifier')) {
$this->_retvalue .= "\$_smarty_tpl->smarty->plugin_handler->".$this->yystack[$this->yyidx + -3]->minor[0] . "(array(ob_get_clean()". $this->yystack[$this->yyidx + -2]->minor ."),'modifier');?>";
if ($this->smarty->plugin_handler->loadSmartyPlugin($this->yystack[$this->yyidx + -3]->minor[0],'modifier')) {
$this->_retvalue .= "\$_smarty_tpl->smarty->plugin_handler->executeModifier('".$this->yystack[$this->yyidx + -3]->minor[0] . "',array(ob_get_clean()" . $this->yystack[$this->yyidx + -2]->minor. "),".$this->yystack[$this->yyidx + -3]->minor[1].");?>";
} else {
if ($this->yystack[$this->yyidx + -3]->minor[0] == 'isset' || $this->yystack[$this->yyidx + -3]->minor[0] == 'empty' || is_callable($this->yystack[$this->yyidx + -3]->minor[0])) {
if (is_callable($this->yystack[$this->yyidx + -3]->minor[0])) {
if (!$this->template->security || $this->smarty->security_handler->isTrustedModifier($this->yystack[$this->yyidx + -3]->minor[0], $this->compiler)) {
$this->_retvalue .= $this->yystack[$this->yyidx + -3]->minor[0] . "(ob_get_clean()". $this->yystack[$this->yyidx + -2]->minor .");?>";
$this->_retvalue .= "\$_smarty_tpl->smarty->plugin_handler->executeModifier('".$this->yystack[$this->yyidx + -3]->minor[0] . "',array(ob_get_clean()" . $this->yystack[$this->yyidx + -2]->minor. "),".$this->yystack[$this->yyidx + -3]->minor[1].");?>";
}
} else {
$this->compiler->trigger_template_error ("unknown modifier \"" . $this->yystack[$this->yyidx + -3]->minor[0] . "\"");
}
}
}
}
#line 1990 "internal.templateparser.php"
#line 165 "internal.templateparser.y"
function yy_r19(){ preg_match('/\s*/',$this->yystack[$this->yyidx + -3]->minor,$s); $this->_retvalue = $s[0].$this->compiler->compileTag($this->yystack[$this->yyidx + -2]->minor.'close',$this->yystack[$this->yyidx + -1]->minor); }
@@ -2053,13 +2053,13 @@ static public $yy_action = array(
function yy_r37(){$this->_retvalue = '$_smarty_tpl->getStreamVariable(\''. $this->yystack[$this->yyidx + -2]->minor .'://'. $this->yystack[$this->yyidx + 0]->minor . '\')'; }
#line 2059 "internal.templateparser.php"
#line 227 "internal.templateparser.y"
function yy_r38(){
function yy_r38(){
if ($this->smarty->plugin_handler->loadSmartyPlugin($this->yystack[$this->yyidx + -1]->minor[0],'modifier')) {
$this->_retvalue = "\$_smarty_tpl->smarty->plugin_handler->".$this->yystack[$this->yyidx + -1]->minor[0] . "(array(". $this->yystack[$this->yyidx + -2]->minor . $this->yystack[$this->yyidx + 0]->minor ."),'modifier')";
$this->_retvalue = "\$_smarty_tpl->smarty->plugin_handler->executeModifier('".$this->yystack[$this->yyidx + -1]->minor[0] . "',array(". $this->yystack[$this->yyidx + -2]->minor . $this->yystack[$this->yyidx + 0]->minor. "),".$this->yystack[$this->yyidx + -1]->minor[1].")";
} else {
if ($this->yystack[$this->yyidx + -1]->minor[0] == 'isset' || $this->yystack[$this->yyidx + -1]->minor[0] == 'empty' || is_callable($this->yystack[$this->yyidx + -1]->minor[0])) {
if (is_callable($this->yystack[$this->yyidx + -1]->minor[0])) {
if (!$this->template->security || $this->smarty->security_handler->isTrustedModifier($this->yystack[$this->yyidx + -1]->minor[0], $this->compiler)) {
$this->_retvalue = $this->yystack[$this->yyidx + -1]->minor[0] . "(". $this->yystack[$this->yyidx + -2]->minor . $this->yystack[$this->yyidx + 0]->minor .")";
$this->_retvalue = "\$_smarty_tpl->smarty->plugin_handler->executeModifier('".$this->yystack[$this->yyidx + -1]->minor[0] . "',array(". $this->yystack[$this->yyidx + -2]->minor . $this->yystack[$this->yyidx + 0]->minor. "),".$this->yystack[$this->yyidx + -1]->minor[1].")";
}
} else {
$this->compiler->trigger_template_error ("unknown modifier \"" . $this->yystack[$this->yyidx + -1]->minor[0] . "\"");
@@ -2205,10 +2205,10 @@ static public $yy_action = array(
function yy_r96(){ return; }
#line 2211 "internal.templateparser.php"
#line 393 "internal.templateparser.y"
function yy_r97(){ $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor,true); }
function yy_r97(){ $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor,'false'); }
#line 2214 "internal.templateparser.php"
#line 394 "internal.templateparser.y"
function yy_r98(){ $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor,false); }
function yy_r98(){ $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor,'true'); }
#line 2217 "internal.templateparser.php"
#line 401 "internal.templateparser.y"
function yy_r99(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; }