WIP for performance improvements.

Removed $smarty->_current_file and $smarty->allow_ambiguous_resources properties, both unused. Removed public Source::filepath property.
Cached an Compiled files (and Exceptions) no longer rely on the filepath being set. Removed explicit tests for cached and compiled filenames. The exact implementation is not important. Added tests for compile_check property, fixing a file_exists check that would always be done on source template files, even when compile_check was true. Remove code duplication between Source en Config classes. Added a local $_smarty_current_dir to the generated code files for backwards compatability for {$smarty.current_dir}.
This commit is contained in:
Simon Wisselink
2023-02-03 15:50:31 +01:00
parent cd158566d0
commit 7408c18cdc
55 changed files with 1510 additions and 1472 deletions

View File

@@ -54,6 +54,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed direct access to `$smarty->cache_dir`. Use `$smarty->setCacheDir()`.
- Removed `$smarty->loadPlugin()`, use `$smarty->registerPlugin()` instead.
- Removed `$smarty->appendByRef()` and `$smarty->assignByRef()`.
- Removed `$smarty->_current_file`
- Removed `$smarty->allow_ambiguous_resources`, but ambiguous resources handlers should still work
### Fixed
- `$smarty->muteUndefinedOrNullWarnings()` now also mutes PHP7 notices for undefined array indexes [#736](https://github.com/smarty-php/smarty/issues/736)

View File

@@ -1,5 +1,10 @@
# @TODO
## Performance improvements
- context: pass template variables in an array
- why do we do 300k assign() calls? (answer: foreach?)
- debugging: see if removing debugging code speeds up
## Review direct variable property access
- review ->value{$index} in ForTag
@@ -12,9 +17,6 @@
## Review public static vars
- such as _CHARSET and _IS_WINDOWS
## Benchmark
- benchmark to see that performance hasn't degraded
## Block / inheritance
- Consider phasing out $smarty.block.child as this reverses the inheritance hierarchy and might cause infinite loops
when combined with $smarty.block.parent

View File

@@ -36,7 +36,7 @@ class File extends Base
$source = $_template->getSource();
$smarty = $_template->getSmarty();
$_compile_dir_sep = $smarty->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
$_filepath = sha1($source->uid . $smarty->_joined_template_dir);
$_filepath = $source->uid;
$cached->filepath = $smarty->getCacheDir();
if (isset($_template->cache_id)) {
$cached->filepath .= preg_replace(
@@ -61,11 +61,8 @@ class File extends Base
DIRECTORY_SEPARATOR .
$_filepath[ 4 ] . $_filepath[ 5 ] . DIRECTORY_SEPARATOR;
}
$cached->filepath .= $_filepath;
$basename = $source->getBasename();
if (!empty($basename)) {
$cached->filepath .= '.' . $basename;
}
$cached->filepath .= $_filepath . '_' . $source->getBasename();
if ($smarty->cache_locking) {
$cached->lock_id = $cached->filepath . '.lock';
}
@@ -205,7 +202,7 @@ class File extends Base
if (isset($resource_name)) {
$_save_stat = $smarty->caching;
$smarty->caching = \Smarty\Smarty::CACHING_LIFETIME_CURRENT;
$tpl = $smarty->createTemplate($resource_name);
$tpl = $smarty->doCreateTemplate($resource_name);
$smarty->caching = $_save_stat;
// remove from template cache
if ($tpl->getSource()->exists) {

View File

@@ -82,7 +82,7 @@ class SpecialVariableCompiler extends Base {
$compiled_ref = '$_' . smarty_strtoupper_ascii($variable);
break;
case 'template':
return 'basename($_smarty_tpl->getSource()->filepath)';
return '$_smarty_tpl->template_resource';
case 'template_object':
if (isset($compiler->getSmarty()->security_policy)) {
$compiler->trigger_template_error("(secure mode) template_object not permitted");
@@ -90,7 +90,7 @@ class SpecialVariableCompiler extends Base {
}
return '$_smarty_tpl';
case 'current_dir':
return 'dirname($_smarty_tpl->getSource()->filepath)';
return '$_smarty_current_dir';
case 'version':
return "\\Smarty\\Smarty::SMARTY_VERSION";
case 'const':

View File

@@ -84,7 +84,6 @@ class Block extends Inheritance {
]
);
// @TODO what is this for?
$compiler->getParser()->current_buffer = new Template();
$compiler->getTemplate()->getCompiled()->setNocacheCode(false);
$compiler->suppressNocacheProcessing = true;

View File

@@ -50,6 +50,9 @@ class BlockClose extends Inheritance {
$output .= "public \${$property} = " . var_export($value, true) . ";\n";
}
$output .= "public function callBlock(\\Smarty\\Template \$_smarty_tpl) {\n";
$output .= (new \Smarty\Compiler\CodeFrame($compiler->getTemplate()))->insertLocalVariables();
if ($compiler->getTemplate()->getCompiled()->getNocacheCode()) {
$output .= "\$_smarty_tpl->getCached()->hashes['{$compiler->getTemplate()->getCompiled()->nocache_hash}'] = true;\n";
}
@@ -104,4 +107,5 @@ class BlockClose extends Inheritance {
$compiler->suppressNocacheProcessing = true;
return $output;
}
}

View File

@@ -103,7 +103,7 @@ class ExtendsTag extends Inheritance {
$compiler->getParser()->template_postfix[] = new \Smarty\ParseTree\Tag(
$compiler->getParser(),
'<?php $_smarty_tpl->getInheritance()->endChild($_smarty_tpl' .
(isset($template) ? ", {$template}" : '') . ");\n?>"
(isset($template) ? ", {$template}, \$_smarty_current_dir" : '') . ");\n?>"
);
}

View File

@@ -48,11 +48,12 @@ class FunctionClose extends Base {
unset($_parameter['name']);
// default parameter
$_paramsArray = $this->formatParamsArray($_attr);
$_paramsCode = (new \Smarty\Compiler\CodeFrame($compiler->getTemplate()))->insertLocalVariables();
if (!empty($_paramsArray)) {
$_params = 'array(' . implode(',', $_paramsArray) . ')';
$_paramsCode = "\$params = array_merge($_params, \$params);\n";
} else {
$_paramsCode = '';
$_paramsCode .= "\$params = array_merge($_params, \$params);\n";
}
$_functionCode = $compiler->getParser()->current_buffer;
// setup buffer for template function code
@@ -67,6 +68,7 @@ class FunctionClose extends Base {
$output .= $compiler->cStyleComment(" {$_funcNameCaching} ") . "\n";
$output .= "if (!function_exists('{$_funcNameCaching}')) {\n";
$output .= "function {$_funcNameCaching} (\\Smarty\\Template \$_smarty_tpl,\$params) {\n";
$output .= "ob_start();\n";
$output .= "\$_smarty_tpl->getCompiled()->setNocacheCode(true);\n";
$output .= $_paramsCode;
@@ -149,7 +151,6 @@ class FunctionClose extends Base {
* @return string
*/
public function removeNocache($match) {
// @TODO why is this here, and will the $this->compiler property survive long enough for the callback?
$hash = $this->compiler->getTemplate()->getCompiled()->nocache_hash;
$code =
preg_replace(

View File

@@ -108,7 +108,6 @@ class IncludeTag extends Base {
$_caching = Smarty::CACHING_OFF;
// caching was on and {include} is not in nocache mode
// @TODO see if we can do without this
if ($compiler->getTemplate()->caching && !$compiler->isNocacheActive()) {
$_caching = \Smarty\Template::CACHING_NOCACHE_CODE;
}
@@ -178,7 +177,7 @@ class IncludeTag extends Base {
$_output .= "ob_start();\n";
}
$_output .= "\$_smarty_tpl->renderSubTemplate({$fullResourceName}, $_cache_id, \$_smarty_tpl->compile_id, " .
"$_caching, $_cache_lifetime, $_vars, (int) {$_scope});\n";
"$_caching, $_cache_lifetime, $_vars, (int) {$_scope}, \$_smarty_current_dir);\n";
if (isset($_assign)) {
$_output .= "\$_smarty_tpl->assign({$_assign}, ob_get_clean(), false, {$_scope});\n";
}

View File

@@ -59,13 +59,16 @@ class CodeFrame
"<?php\n/* Smarty version %s, created on %s\n from '%s' */\n\n",
$properties[ 'version' ],
date("Y-m-d H:i:s"),
str_replace('*/', '* /', $this->_template->getSource()->filepath)
str_replace('*/', '* /', $this->_template->getSource()->getFullResourceName())
);
$output .= "/* @var \\Smarty\\Template \$_smarty_tpl */\n";
$dec = "\$_smarty_tpl->" . ($cache ? "getCached()" : "getCompiled()");
$dec .= "->isFresh(\$_smarty_tpl, " . var_export($properties, true) . ')';
$output .= "if ({$dec}) {\n";
$output .= "function {$properties['unifunc']} (\\Smarty\\Template \$_smarty_tpl) {\n";
$output .= $this->insertLocalVariables();
if (!$cache && !empty($compiler->tpl_function)) {
$output .= '$_smarty_tpl->getSmarty()->getRuntime(\'TplFunction\')->registerTplFunctions($_smarty_tpl, ';
$output .= var_export($compiler->tpl_function, true);
@@ -113,4 +116,11 @@ class CodeFrame
}
return $output;
}
/**
* @return string
*/
public function insertLocalVariables(): string {
return '$_smarty_current_dir = ' . var_export(dirname($this->_template->getSource()->getFilepath()), true) . ";\n";
}
}

View File

@@ -84,7 +84,7 @@ class Configfile extends BaseCompiler {
$this->template = $template;
$this->template->getCompiled()->file_dependency[$this->template->getSource()->uid] =
[
$this->template->getSource()->filepath,
$this->template->getSource()->getResourceName(),
$this->template->getSource()->getTimeStamp(),
$this->template->getSource()->type,
];
@@ -126,7 +126,7 @@ class Configfile extends BaseCompiler {
"<?php /* Smarty version %s, created on %s\n compiled from '%s' */ ?>\n",
\Smarty\Smarty::SMARTY_VERSION,
date("Y-m-d H:i:s"),
str_replace('*/', '* /', $this->template->getSource()->filepath)
str_replace('*/', '* /', $this->template->getSource()->getFullResourceName())
);
$code = '<?php $_smarty_tpl->parent->assignConfigVars(' .
var_export($this->config_data, true) . ', $_smarty_tpl->getValue("sections")); ?>';
@@ -151,7 +151,7 @@ class Configfile extends BaseCompiler {
}
$match = preg_split("/\n/", $this->lex->data);
$error_text =
"Syntax error in config file '{$this->template->getSource()->filepath}' on line {$line} '{$match[$line - 1]}' ";
"Syntax error in config file '{$this->template->getSource()->getFullResourceName()}' on line {$line} '{$match[$line - 1]}' ";
if (isset($args)) {
// individual error message
$error_text .= $args;

View File

@@ -403,12 +403,11 @@ class Template extends BaseCompiler {
if ($this->template->getSource()->handler->checkTimestamps()) {
$this->parent_compiler->getTemplate()->getCompiled()->file_dependency[$this->template->getSource()->uid] =
[
$this->template->getSource()->filepath,
$this->template->getSource()->getResourceName(),
$this->template->getSource()->getTimeStamp(),
$this->template->getSource()->type,
];
}
$this->smarty->_current_file = $this->template->getSource()->filepath;
// get template source
if (!empty($this->template->getSource()->components)) {
// we have array of inheritance templates by extends: resource
@@ -811,7 +810,7 @@ class Template extends BaseCompiler {
)
);
} else {
$templateName = $this->template->getSource()->type . ':' . $this->template->getSource()->filepath;
$templateName = $this->template->getSource()->getFullResourceName();
}
// $line += $this->trace_line_offset;
$match = preg_split("/\n/", $lex->data);
@@ -848,12 +847,12 @@ class Template extends BaseCompiler {
$e = new CompilerException(
$error_text,
0,
$this->template->getSource()->filepath,
$this->template->getSource()->getFullResourceName(),
$line
);
$e->source = trim(preg_replace('![\t\r\n]+!', ' ', $match[$line - 1]));
$e->desc = $args;
$e->template = $this->template->getSource()->filepath;
$e->template = $this->template->getSource()->getFullResourceName();
throw $e;
}
@@ -1128,13 +1127,6 @@ class Template extends BaseCompiler {
return $this->has_code ? $_output : null;
}
// @TODO: This code was in here in v4, but it might not do anything (anymore)
// foreach ($args['_attr'] ?? [] as $attribute) {
// if (is_array($attribute)) {
// $args = array_merge($args, $attribute);
// }
// }
// remaining tastes: (object-)function, (object-function-)block, custom-compiler
// opening and closing tags for these are handled with the same handler
$base_tag = $this->getBaseTag($tag);
@@ -1485,5 +1477,4 @@ class Template extends BaseCompiler {
public function getTagStack(): array {
return $this->_tag_stack;
}
}

View File

@@ -51,7 +51,7 @@ class Data
* Default scope for new variables
* @var int
*/
private $defaultScope = self::SCOPE_LOCAL;
protected $defaultScope = self::SCOPE_LOCAL;
/**
* create Smarty data object
@@ -454,11 +454,11 @@ class Data
*/
public function configLoad($config_file, $sections = null)
{
$template = $this->getSmarty()->createTemplate($config_file, null, null, $this, null, null, null, true);
$template = $this->getSmarty()->doCreateTemplate($config_file, null, null, $this, null, null, true);
$template->caching = Smarty::CACHING_OFF;
$template->assign('sections', (array) $sections ?? []);
// trigger a call to $this->assignConfigVars
$template->getCompiled(true)->render($template);
$template->fetch();
return $this;
}

View File

@@ -213,8 +213,6 @@ class Debug extends Data
$debObj->registered_filters = array();
$debObj->escape_html = true;
$debObj->caching = \Smarty::CACHING_OFF;
$debObj->compile_id = null;
$debObj->cache_id = null;
// prepare information of assigned variables
$ptr = $this->get_debug_vars($obj);
$_assigned_vars = $ptr->tpl_vars;
@@ -222,7 +220,7 @@ class Debug extends Data
$_config_vars = $ptr->config_vars;
ksort($_config_vars);
$debugging = $smarty->debugging;
$_template = $debObj->createTemplate($debObj->debug_tpl);
$_template = $debObj->doCreateTemplate($debObj->debug_tpl);
if ($obj instanceof \Smarty\Template) {
$_template->assign('template_name', $obj->getSource()->type . ':' . $obj->getSource()->name);
} elseif ($obj instanceof Smarty || $full) {
@@ -305,10 +303,7 @@ class Debug extends Data
private function get_key(\Smarty\Template $template)
{
static $_is_stringy = array('string' => true, 'eval' => true);
// calculate Uid if not already done
if ($template->getSource()->uid === '') {
$template->getSource()->filepath;
}
$key = $template->getSource()->uid;
if (isset($this->template_data[ $this->index ][ $key ])) {
return $key;
@@ -326,11 +321,7 @@ class Debug extends Data
*/
public function ignore(\Smarty\Template $template)
{
// calculate Uid if not already done
if ($template->getSource()->uid === '') {
$template->getSource()->filepath;
}
$this->ignore_uid[ $template->getSource()->uid ] = true;
$this->ignore_uid[$template->getSource()->uid] = true;
}
/**
@@ -377,7 +368,7 @@ class Debug extends Data
$this->template_data[$this->index][$key]['name'] =
'\'' . substr($template->getSource()->name, 0, 25) . '...\'';
} else {
$this->template_data[$this->index][$key]['name'] = $template->getSource()->filepath;
$this->template_data[$this->index][$key]['name'] = $template->getSource()->getResourceName();
}
$this->template_data[$this->index][$key]['compile_time'] = 0;
$this->template_data[$this->index][$key]['render_time'] = 0;

View File

@@ -96,30 +96,6 @@ abstract class BasePlugin
throw new \Smarty\Exception("Unknown resource type '{$type}'");
}
/**
* extract resource_type and resource_name from template_resource and config_resource
*
* @note "C:/foo.tpl" was forced to file resource up till Smarty 3.1.3 (including).
*
* @param string $resource_name template_resource or config_resource to parse
* @param string $default_resource the default resource_type defined in $smarty
*
* @return array with parsed resource name and type
*/
public static function parseResourceName($resource_name, $default_resource)
{
if (preg_match('/^([A-Za-z0-9_\-]{2,})[:]/', $resource_name, $match)) {
$type = $match[ 1 ];
$name = substr($resource_name, strlen($match[ 0 ]));
} else {
// no resource given, use default
// or single character before the colon is not a resource type, but part of the filepath
$type = $default_resource;
$name = $resource_name;
}
return array($name, $type);
}
/**
* Load template's source into current template object
*

View File

@@ -45,20 +45,19 @@ abstract class CustomPlugin extends BasePlugin {
}
/**
* populate Source Object with meta data from Resource
* populate Source Object with metadata from Resource
*
* @param Source $source source object
* @param Template $_template template object
* @param Template|null $_template template object
*/
public function populate(Source $source, Template $_template = null) {
$source->filepath = $source->type . ':' . $this->generateSafeName($source->name);
$source->uid = sha1($source->type . ':' . $source->name);
$mtime = $this->fetchTimestamp($source->name);
if ($mtime !== null) {
$source->timestamp = $mtime;
} else {
$this->fetch($source->name, $content, $timestamp);
$source->timestamp = isset($timestamp) ? $timestamp : false;
$source->timestamp = $timestamp ?? false;
if (isset($content)) {
$source->content = $content;
}

View File

@@ -32,17 +32,13 @@ class ExtendsPlugin extends BasePlugin
$exists = true;
foreach ($components as $component) {
$_s = Source::load(null, $smarty, $component);
if ($_s->type === 'php') {
throw new \Smarty\Exception("Resource type {$_s->type} cannot be used with the extends resource type");
}
$sources[ $_s->uid ] = $_s;
$uid .= $_s->filepath;
$uid .= $_s->uid;
if ($_template) {
$exists = $exists && $_s->exists;
}
}
$source->components = $sources;
$source->filepath = $_s->filepath;
$source->uid = sha1($uid . $source->getSmarty()->_joined_template_dir);
$source->exists = $exists;
if ($_template) {
@@ -76,7 +72,7 @@ class ExtendsPlugin extends BasePlugin
public function getContent(Source $source)
{
if (!$source->exists) {
throw new \Smarty\Exception("Unable to load template '{$source->type}:{$source->name}'");
throw new \Smarty\Exception("Unable to load '{$source->type}:{$source->name}'");
}
$_components = array_reverse($source->components);
$_content = '';
@@ -97,7 +93,7 @@ class ExtendsPlugin extends BasePlugin
*/
public function getBasename(Source $source)
{
return str_replace(':', '.', basename($source->filepath));
return str_replace(':', '.', basename($source->getResourceName()));
}
/*

View File

@@ -10,6 +10,7 @@
namespace Smarty\Resource;
use Smarty\Smarty;
use Smarty\Template;
use Smarty\Template\Source;
use Smarty\Exception;
@@ -24,25 +25,26 @@ use Smarty\Exception;
class FilePlugin extends BasePlugin {
/**
* populate Source Object with meta data from Resource
* populate Source Object with metadata from Resource
*
* @param Source $source source object
* @param Template $_template template object
* @param Template|null $_template template object
*
* @throws \Smarty\Exception
* @throws Exception
*/
public function populate(Source $source, Template $_template = null) {
$source->filepath = $this->buildFilepath($source, $_template);
if ($source->filepath !== false) {
$source->uid = sha1(
$source->name . ($source->isConfig ? $source->getSmarty()->_joined_config_dir :
$source->getSmarty()->_joined_template_dir)
);
if ($path = $this->getFilePath($source->name, $source->getSmarty(), $source->isConfig)) {
if (isset($source->getSmarty()->security_policy) && is_object($source->getSmarty()->security_policy)) {
$source->getSmarty()->security_policy->isTrustedResourceDir($source->filepath, $source->isConfig);
$source->getSmarty()->security_policy->isTrustedResourceDir($path, $source->isConfig);
}
$source->exists = true;
$source->uid = sha1(
$source->filepath . ($source->isConfig ? $source->getSmarty()->_joined_config_dir :
$source->getSmarty()->_joined_template_dir)
);
$source->timestamp = filemtime($source->filepath);
$source->timestamp = filemtime($path);
} else {
$source->timestamp = $source->exists = false;
}
@@ -54,11 +56,11 @@ class FilePlugin extends BasePlugin {
* @param Source $source source object
*/
public function populateTimestamp(Source $source) {
if (!$source->exists) {
$source->timestamp = $source->exists = is_file($source->filepath);
if (!$source->exists && $path = $this->getFilePath($source->name, $source->getSmarty(), $source->isConfig)) {
$source->timestamp = $source->exists = is_file($path);
}
if ($source->exists) {
$source->timestamp = filemtime($source->filepath);
if ($source->exists && $path) {
$source->timestamp = filemtime($path);
}
}
@@ -72,7 +74,7 @@ class FilePlugin extends BasePlugin {
*/
public function getContent(Source $source) {
if ($source->exists) {
return file_get_contents($source->filepath);
return file_get_contents($this->getFilePath($source->getResourceName(), $source->getSmarty(), $source->isConfig()));
}
throw new Exception(
'Unable to read ' . ($source->isConfig ? 'config' : 'template') .
@@ -88,43 +90,30 @@ class FilePlugin extends BasePlugin {
* @return string resource's basename
*/
public function getBasename(Source $source) {
return basename($source->filepath);
return basename($source->getResourceName());
}
/**
* build template filepath by traversing the template_dir array
*
* @param Source $source source object
* @param Template $_template template object
* @param $file
* @param Smarty $smarty
* @param bool $isConfig
*
* @return string fully qualified filepath
* @throws Exception
*/
protected function buildFilepath(Source $source, Template $_template = null) {
$file = $source->name;
public function getFilePath($file, \Smarty\Smarty $smarty, bool $isConfig = false) {
// absolute file ?
if ($file[0] === '/' || $file[1] === ':') {
$file = $source->getSmarty()->_realpath($file, true);
$file = $smarty->_realpath($file, true);
return is_file($file) ? $file : false;
}
// go relative to a given template?
if ($file[0] === '.' && $_template && $_template->_isSubTpl()
&& preg_match('#^[.]{1,2}[\\\/]#', $file)
) {
if ($_template->parent->getSource()->type !== 'file' && $_template->parent->getSource()->type !== 'extends') {
throw new Exception("Template '{$file}' cannot be relative to template of resource type '{$_template->parent->getSource()->type}'");
}
// normalize path
$path =
$source->getSmarty()->_realpath(dirname($_template->parent->getSource()->filepath) . DIRECTORY_SEPARATOR . $file);
// files relative to a template only get one shot
return is_file($path) ? $path : false;
}
// normalize DIRECTORY_SEPARATOR
if (strpos($file, DIRECTORY_SEPARATOR === '/' ? '\\' : '/') !== false) {
$file = str_replace(DIRECTORY_SEPARATOR === '/' ? '\\' : '/', DIRECTORY_SEPARATOR, $file);
}
$_directories = $source->getSmarty()->getTemplateDir(null, $source->isConfig);
$_directories = $smarty->getTemplateDir(null, $isConfig);
// template_dir index?
if ($file[0] === '[' && preg_match('#^\[([^\]]+)\](.+)$#', $file, $fileMatch)) {
$file = $fileMatch[2];
@@ -160,16 +149,32 @@ class FilePlugin extends BasePlugin {
foreach ($_directories as $_directory) {
$path = $_directory . $file;
if (is_file($path)) {
return (strpos($path, '.' . DIRECTORY_SEPARATOR) !== false) ? $source->getSmarty()->_realpath($path) : $path;
return (strpos($path, '.' . DIRECTORY_SEPARATOR) !== false) ? $smarty->_realpath($path) : $path;
}
}
if (!isset($_index_dirs)) {
// Could be relative to cwd
$path = $source->getSmarty()->_realpath($file, true);
$path = $smarty->_realpath($file, true);
if (is_file($path)) {
return $path;
}
}
return false;
}
/**
* Returns the timestamp of the resource indicated by $resourceName, or false if it doesn't exist.
*
* @param string $resourceName
* @param Smarty $smarty
* @param bool $isConfig
*
* @return false|int
*/
public function getResourceNameTimestamp(string $resourceName, \Smarty\Smarty $smarty, bool $isConfig = false) {
if ($path = $this->getFilePath($resourceName, $smarty, $isConfig)) {
return filemtime($path);
}
return false;
}
}

View File

@@ -34,11 +34,6 @@ class StreamPlugin extends RecompiledPlugin {
* @return void
*/
public function populate(Source $source, Template $_template = null) {
if (strpos($source->resource, '://') !== false) {
$source->filepath = $source->resource;
} else {
$source->filepath = str_replace(':', '://', $source->resource);
}
$source->uid = false;
$source->content = $this->getContent($source);
$source->timestamp = $source->exists = !!$source->content;
@@ -52,9 +47,16 @@ class StreamPlugin extends RecompiledPlugin {
* @return string template source
*/
public function getContent(Source $source) {
if (strpos($source->getResourceName(), '://') !== false) {
$filepath = $source->getResourceName();
} else {
$filepath = str_replace(':', '://', $source->getFullResourceName());
}
$t = '';
// the availability of the stream has already been checked in Smarty\Resource\Base::fetch()
$fp = fopen($source->filepath, 'r+');
$fp = fopen($filepath, 'r+');
if ($fp) {
while (!feof($fp) && ($current_line = fgets($fp)) !== false) {
$t .= $current_line;

View File

@@ -33,7 +33,7 @@ class StringEval extends RecompiledPlugin
*/
public function populate(\Smarty\Template\Source $source, \Smarty\Template $_template = null)
{
$source->uid = $source->filepath = sha1($source->name);
$source->uid = sha1($source->name);
$source->timestamp = $source->exists = true;
}

View File

@@ -24,7 +24,7 @@ use Smarty\Template\Source;
class StringPlugin extends BasePlugin {
/**
* populate Source Object with meta data from Resource
* populate Source Object with metadata from Resource
*
* @param Source $source source object
* @param Template $_template template object
@@ -32,7 +32,7 @@ class StringPlugin extends BasePlugin {
* @return void
*/
public function populate(Source $source, Template $_template = null) {
$source->uid = $source->filepath = sha1($source->name . $source->getSmarty()->_joined_template_dir);
$source->uid = sha1($source->name);
$source->timestamp = $source->exists = true;
}

View File

@@ -102,7 +102,7 @@ class InheritanceRuntime {
* @throws \Exception
* @throws \Smarty\Exception
*/
public function endChild(Template $tpl, $template = null) {
public function endChild(Template $tpl, $template = null, ?string $currentDir = null) {
--$this->inheritanceLevel;
if (!$this->inheritanceLevel) {
ob_end_clean();
@@ -114,7 +114,10 @@ class InheritanceRuntime {
$tpl->cache_id,
$tpl->compile_id,
$tpl->caching ? \Smarty\Template::CACHING_NOCACHE_CODE : 0,
$tpl->cache_lifetime
$tpl->cache_lifetime,
[],
null,
$currentDir
);
}
}
@@ -221,7 +224,7 @@ class InheritanceRuntime {
$this->callBlock($block->parent, $tpl);
} else {
throw new Exception("inheritance: illegal '{\$smarty.block.parent}' used in child template '" .
"{$tpl->getInheritance()->sources[$block->tplIndex]->filepath}' block '{$block->name}'");
"{$tpl->getInheritance()->sources[$block->tplIndex]->getResourceName()}' block '{$block->name}'");
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,7 @@
namespace Smarty;
use Smarty\Resource\BasePlugin;
use Smarty\Runtime\InheritanceRuntime;
use Smarty\Template\Source;
use Smarty\Template\Cached;
@@ -154,9 +155,9 @@ class Template extends TemplateBase {
$this->smarty->getDebug()->start_template($this, $display);
}
// checks if template exists
if (!$this->getSource()->exists) {
if ($this->compile_check && !$this->getSource()->exists) {
throw new Exception(
"Unable to load template '{$this->getSource()->type}:{$this->getSource()->name}'" .
"Unable to load '{$this->getSource()->type}:{$this->getSource()->name}'" .
($this->_isSubTpl() ? " in '{$this->parent->template_resource}'" : '')
);
}
@@ -174,16 +175,9 @@ class Template extends TemplateBase {
// read from cache or render
if ($this->caching === \Smarty\Smarty::CACHING_LIFETIME_CURRENT || $this->caching === \Smarty\Smarty::CACHING_LIFETIME_SAVED) {
if ($this->getCached()->cache_id !== $this->cache_id || $this->getCached()->compile_id !== $this->compile_id) {
$this->getCached(true);
}
$this->getCached()->render($this, $no_output_filter);
} else {
$compiled = $this->getCompiled();
if ($compiled->compile_id !== $this->compile_id) {
$compiled = $this->getCompiled(true);
}
$compiled->render($this);
$this->getCompiled()->render($this);
}
} finally {
@@ -254,29 +248,34 @@ class Template extends TemplateBase {
$caching,
$cache_lifetime,
array $extra_vars = [],
int $scope = null
int $scope = null,
?string $currentDir = null
) {
$baseFilePath = $this->source && $this->getSource()->filepath ? dirname($this->getSource()->filepath) : null;
$name = $this->parseResourceName($template_name);
if ($currentDir && preg_match('/^\.{1,2}\//', $name)) {
// relative template resource name, append it to current template name
$template_name = $currentDir . DIRECTORY_SEPARATOR . $name;
}
$tpl = $this->getSmarty()->createTemplate($template_name, $cache_id, $compile_id, $this, $caching, $cache_lifetime, $baseFilePath);
$tpl->setCached($this->getCached()); // re-use the same Cache object across subtemplates to gather hashes and file dependencies.
$tpl->setInheritance($this->getInheritance()); // re-use the same Inheritance object inside the inheritance tree
$tpl = $this->smarty->doCreateTemplate($template_name, $cache_id, $compile_id, $this, $caching, $cache_lifetime);
$tpl->inheritance = $this->getInheritance(); // re-use the same Inheritance object inside the inheritance tree
if ($scope) {
$tpl->setDefaultScope($scope);
$tpl->defaultScope = $scope;
}
// recursive call ?
if ($tpl->getTemplateId() !== $this->getTemplateId() && $caching !== \Smarty\Template::CACHING_NOCACHE_CODE) {
if ($tpl->templateId !== $this->templateId && $caching !== \Smarty\Template::CACHING_NOCACHE_CODE) {
$tpl->getCached(true);
} else {
// re-use the same Cache object across subtemplates to gather hashes and file dependencies.
$tpl->setCached($this->getCached());
}
if (!empty($extra_vars)) {
// set up variable values
foreach ($extra_vars as $_key => $_val) {
$tpl->assign($_key, $_val);
}
foreach ($extra_vars as $_key => $_val) {
$tpl->assign($_key, $_val);
}
if ($tpl->caching === \Smarty\Template::CACHING_NOCACHE_CODE) {
if ($tpl->getCompiled()->getNocacheCode()) {
@@ -287,9 +286,21 @@ 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));
/**
* Remove type indicator from resource name if present.
* E.g. $this->parseResourceName('file:template.tpl') returns 'template.tpl'
*
* @note "C:/foo.tpl" was forced to file resource up till Smarty 3.1.3 (including).
*
* @param string $resource_name template_resource or config_resource to parse
*
* @return string
*/
private function parseResourceName($resource_name): string {
if (preg_match('/^([A-Za-z0-9_\-]{2,}):/', $resource_name, $match)) {
return substr($resource_name, strlen($match[0]));
}
return $resource_name;
}
/**
@@ -392,8 +403,9 @@ class Template extends TemplateBase {
$this->compile_id,
$this->cache_id
);
$cacheResource->populate($this->cached, $this);
if (!$this->isCachingEnabled()) {
if ($this->isCachingEnabled()) {
$cacheResource->populate($this->cached, $this);
} else {
$this->cached->setValid(false);
}
}
@@ -477,7 +489,7 @@ class Template extends TemplateBase {
} else {
$parent_resource = '';
}
throw new Exception("Unable to load template {$this->getSource()->type} '{$this->getSource()->name}'{$parent_resource}");
throw new Exception("Unable to load {$this->getSource()->type} '{$this->getSource()->name}'{$parent_resource}");
}
// @TODO move this logic to Compiled
@@ -564,7 +576,7 @@ class Template extends TemplateBase {
$confObj = parent::configLoad($config_file, $sections);
$this->getCompiled()->file_dependency[ $confObj->getSource()->uid ] =
array($confObj->getSource()->filepath, $confObj->getSource()->getTimeStamp(), $confObj->getSource()->type);
array($confObj->getSource()->getResourceName(), $confObj->getSource()->getTimeStamp(), $confObj->getSource()->type);
return $confObj;
}
@@ -693,4 +705,25 @@ class Template extends TemplateBase {
$this->cached = $cached;
}
/**
* @param string $compile_id
*
* @throws Exception
*/
public function setCompileId($compile_id) {
parent::setCompileId($compile_id);
$this->getCompiled(true);
$this->getCached(true);
}
/**
* @param string $cache_id
*
* @throws Exception
*/
public function setCacheId($cache_id) {
parent::setCacheId($cache_id);
$this->getCached(true);
}
}

View File

@@ -210,10 +210,9 @@ class Cached extends GeneratedPhpFile {
* Process cached template
*
* @param Template $_template template object
* @param bool $update flag if called because cache update
*/
private function process(Template $_template, $update = false) {
if ($this->handler->process($_template, $this, $update) === false) {
private function process(Template $_template) {
if ($this->handler->process($_template, $this) === false) {
$this->valid = false;
}
$this->processed = $this->valid;
@@ -282,15 +281,7 @@ class Cached extends GeneratedPhpFile {
}
$this->removeNoCacheHash($_template, $no_output_filter);
if ($_template->_isSubTpl()) {
// @TODO why is this needed?
$_template->getCompiled()->unifunc = $_template->parent->getCompiled()->unifunc;
}
if (!$this->processed) {
$this->process($_template, true);
}
$this->process($_template);
if ($_template->getSmarty()->debugging) {
$_template->getSmarty()->getDebug()->end_cache($_template);

View File

@@ -72,11 +72,8 @@ class Compiled extends GeneratedPhpFile {
} else {
$this->filepath .= (int)$smarty->escape_html * 2;
}
$this->filepath .= '.' . $source->type;
$basename = $source->getBasename();
if (!empty($basename)) {
$this->filepath .= '.' . $basename;
}
$this->filepath .= '.' . $source->type . '_' . $source->getBasename();
if ($_template->caching) {
$this->filepath .= '.cache';
}
@@ -96,11 +93,7 @@ class Compiled extends GeneratedPhpFile {
* @throws \Smarty\Exception
*/
public function render(Template $_template) {
// checks if template exists
if (!$_template->getSource()->exists) {
$type = $_template->getSource()->isConfig ? 'config' : 'template';
throw new \Smarty\Exception("Unable to load {$type} '{$_template->getSource()->type}:{$_template->getSource()->name}'");
}
if ($_template->getSmarty()->debugging) {
$_template->getSmarty()->getDebug()->start_render($_template);
}
@@ -109,8 +102,10 @@ class Compiled extends GeneratedPhpFile {
}
// @TODO Can't Cached handle this? Maybe introduce an event to decouple.
$_template->getCached()->file_dependency =
array_merge($_template->getCached()->file_dependency, $this->file_dependency);
if ($_template->caching) {
$_template->getCached()->file_dependency =
array_merge($_template->getCached()->file_dependency, $this->file_dependency);
}
$this->getRenderedTemplateCode($_template, $this->unifunc);

View File

@@ -8,7 +8,7 @@ use Smarty\Exception;
/**
* Smarty Config Resource Data Object
* Meta Data Container for Config Files
* Metadata Container for Config Files
*
* @author Uwe Tews
*/
@@ -22,45 +22,15 @@ class Config extends Source {
public $isConfig = true;
/**
* initialize Source Object for given resource
* Either [$_template] or [$smarty, $template_resource] must be specified
*
* @param Template $_template template object
* @param Smarty $smarty smarty object
* @param string $template_resource resource identifier
*
* @return Config Source Object
* @throws Exception
* @var array
*/
public static function load(
Template $_template = null,
Smarty $smarty = null,
$template_resource = null
) {
static $_incompatible_resources = ['extends' => true, 'php' => true];
if ($_template) {
$smarty = $_template->getSmarty();
$template_resource = $_template->template_resource;
}
if (empty($template_resource)) {
throw new Exception('Source: Missing name');
}
// parse resource_name, load resource handler
[$name, $type] = \Smarty\Resource\BasePlugin::parseResourceName($template_resource, $smarty->default_config_type);
// make sure configs are not loaded via anything smarty can't handle
if (isset($_incompatible_resources[$type])) {
throw new Exception("Unable to use resource '{$type}' for config");
}
$source = new Config($smarty, $template_resource, $type, $name);
$source->handler->populate($source, $_template);
if (!$source->exists && isset($smarty->default_config_handler_func)) {
$source->_getDefaultTemplate($smarty->default_config_handler_func);
$source->handler->populate($source, $_template);
}
return $source;
}
static protected $_incompatible_resources = ['extends' => true];
public function createCompiler(): \Smarty\Compiler\BaseCompiler {
return new \Smarty\Compiler\Configfile($this->smarty);
}
protected static function getDefaultHandlerFunc(Smarty $smarty) {
return $smarty->default_config_handler_func;
}
}

View File

@@ -3,6 +3,7 @@
namespace Smarty\Template;
use Smarty\Exception;
use Smarty\Resource\FilePlugin;
use Smarty\Template;
/**
@@ -127,22 +128,27 @@ abstract class GeneratedPhpFile {
protected function checkFileDependencies($file_dependency, Template $_template): bool {
// check file dependencies at compiled code
foreach ($file_dependency as $_file_to_check) {
if ($_file_to_check[2] === 'file') {
if ($_template->getSource()->filepath === $_file_to_check[0]) {
$handler = \Smarty\Resource\BasePlugin::load($_template->getSmarty(), $_file_to_check[2]);
if ($handler instanceof FilePlugin) {
if ($_template->getSource()->getResourceName() === $_file_to_check[0]) {
// do not recheck current template
continue;
}
// file and php types can be checked without loading the respective resource handlers
$mtime = is_file($_file_to_check[0]) ? filemtime($_file_to_check[0]) : false;
$mtime = $handler->getResourceNameTimestamp($_file_to_check[0], $_template->getSmarty(), $_template->getSource()->isConfig);
} else {
$handler = \Smarty\Resource\BasePlugin::load($_template->getSmarty(), $_file_to_check[2]);
if ($handler->checkTimestamps()) {
$source = Source::load($_template, $_template->getSmarty(), $_file_to_check[0]);
// @TODO this doesn't actually check any dependencies, but only the main source file
// and that might to be irrelevant, as the comment "do not recheck current template" above suggests
$source = Source::load($_template, $_template->getSmarty());
$mtime = $source->getTimeStamp();
} else {
continue;
}
}
if ($mtime === false || $mtime > $_file_to_check[1]) {
return false;
}

View File

@@ -2,6 +2,7 @@
namespace Smarty\Template;
use Smarty\Resource\FilePlugin;
use Smarty\Smarty;
use Smarty\Template;
use Smarty\Exception;
@@ -15,7 +16,7 @@ class Source {
/**
* Unique Template ID
*
* @var string
* @var string|null
*/
public $uid = null;
@@ -40,13 +41,6 @@ class Source {
*/
public $name = null;
/**
* Source Filepath
*
* @var string
*/
public $filepath = null;
/**
* Source Timestamp
*
@@ -103,6 +97,11 @@ class Source {
*/
public $content = null;
/**
* @var array
*/
static protected $_incompatible_resources = [];
/**
* create Source Object container
*
@@ -114,11 +113,11 @@ class Source {
* @throws \Smarty\Exception
* @internal param \Smarty\Resource\Base $handler Resource Handler this source object communicates with
*/
public function __construct(Smarty $smarty, $resource, $type, $name) {
public function __construct(Smarty $smarty, $type, $name) {
$this->handler = \Smarty\Resource\BasePlugin::load($smarty, $type);
$this->smarty = $smarty;
$this->resource = $resource;
$this->resource = $type . ':' . $name;
$this->type = $type;
$this->name = $name;
}
@@ -147,7 +146,7 @@ class Source {
throw new Exception('Source: Missing name');
}
// parse resource_name, load resource handler, identify unique resource name
if (preg_match('/^([A-Za-z0-9_\-]{2,})[:]([\s\S]*)$/', $template_resource, $match)) {
if (preg_match('/^([A-Za-z0-9_\-]{2,}):([\s\S]*)$/', $template_resource, $match)) {
$type = $match[1];
$name = $match[2];
} else {
@@ -156,16 +155,25 @@ class Source {
$type = $smarty->default_resource_type;
$name = $template_resource;
}
// create new source object
$source = new Source($smarty, $template_resource, $type, $name);
if (isset(self::$_incompatible_resources[$type])) {
throw new Exception("Unable to use resource '{$type}' for " . __METHOD__);
}
// create new source object
$source = new static($smarty, $type, $name);
$source->handler->populate($source, $_template);
if (!$source->exists && $_template && isset($_template->getSmarty()->default_template_handler_func)) {
$source->_getDefaultTemplate($_template->getSmarty()->default_template_handler_func);
if (!$source->exists && static::getDefaultHandlerFunc($smarty)) {
$source->_getDefaultTemplate(static::getDefaultHandlerFunc($smarty));
$source->handler->populate($source, $_template);
}
return $source;
}
protected static function getDefaultHandlerFunc(Smarty $smarty) {
return $smarty->default_template_handler_func;
}
/**
* Get source time stamp
*
@@ -206,12 +214,11 @@ class Source {
} else {
throw new Exception(
'Default handler: Unable to load ' .
($this->isConfig ? 'config' : 'template') .
" default file '{$_return}' for '{$this->type}:{$this->name}'"
"default file '{$_return}' for '{$this->type}:{$this->name}'"
);
}
$this->name = $this->filepath = $_return;
$this->uid = sha1($this->filepath);
$this->name = $_return;
$this->uid = sha1($_return);
} elseif ($_return === true) {
$this->content = $_content;
$this->exists = true;
@@ -244,4 +251,35 @@ class Source {
return $this->handler->getBasename($this);
}
/**
* Return source name
* e.g.: 'sub/index.tpl'
*
* @return string
*/
public function getResourceName(): string {
return (string) $this->name;
}
/**
* Return source name, including the type prefix.
* e.g.: 'file:sub/index.tpl'
*
* @return string
*/
public function getFullResourceName(): string {
return $this->type . ':' . $this->name;
}
public function getFilepath(): string {
if ($this->handler instanceof FilePlugin) {
return $this->handler->getFilePath($this->name, $this->smarty, $this->isConfig);
}
return '.';
}
public function isConfig(): bool {
return $this->isConfig;
}
}

View File

@@ -398,7 +398,7 @@ KEY `name` (`name`)
return sha1($this->normalizePath($this->smarty->getTemplateDir(0) . $name) .
$this->smarty->_joined_template_dir);
}
return sha1($tpl->getSource()->filepath . $this->smarty->_joined_template_dir);
return sha1($tpl->getSource()->uid . $this->smarty->_joined_template_dir);
case 'mysqltest':
case 'mysql':
return sha1($type . ':' . $name);
@@ -564,7 +564,7 @@ KEY `name` (`name`)
$_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null;
$sp = $this->buildSourcePath($tpl, $name, $type, $dir);
$uid = $this->buildUid($tpl, $sp, $name, $type);
$_filepath = sha1($uid . $this->smarty->_joined_template_dir);
$_filepath = $uid;
// if use_sub_dirs, break file into directories
if ($sub) {
$_filepath =

View File

@@ -10,10 +10,6 @@ include_once __DIR__ . '/../_shared/CacheResourceTestCommon.php';
/**
* class for cache resource file tests
*
*
*
*
*/
class CacheResourceFileTest extends CacheResourceTestCommon
{
@@ -41,8 +37,8 @@ class CacheResourceFileTest extends CacheResourceTestCommon
$this->smarty->cache_lifetime = 1000;
$this->smarty->setUseSubDirs(true);
$tpl = $this->smarty->createTemplate('helloworld.tpl');
$this->assertEquals($this->buildCachedPath($tpl, true, null, null, 'helloworld.tpl', $type = 'file', $this->smarty->getTemplateDir(0), 'file')
, $tpl->getCached()->filepath);
$this->assertRegExp('/.*\/([a-f0-9]{2}\/){3}.*.php/', $tpl->getCached()->filepath);
}
/**
@@ -54,8 +50,8 @@ class CacheResourceFileTest extends CacheResourceTestCommon
$this->smarty->cache_lifetime = 1000;
$this->smarty->setUseSubDirs(true);
$tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar');
$this->assertEquals($this->buildCachedPath($tpl, true, 'foo|bar', null, 'helloworld.tpl', $type = 'file', $this->smarty->getTemplateDir(0), 'file')
, $tpl->getCached()->filepath);
$this->assertRegExp('/.*\/foo\/bar\/([a-f0-9]{2}\/){3}.*.php/', $tpl->getCached()->filepath);
}
/**
@@ -67,8 +63,7 @@ class CacheResourceFileTest extends CacheResourceTestCommon
$this->smarty->cache_lifetime = 1000;
$this->smarty->setUseSubDirs(true);
$tpl = $this->smarty->createTemplate('helloworld.tpl', null, 'blar');
$this->assertEquals($this->buildCachedPath($tpl, true, null, 'blar', 'helloworld.tpl', $type = 'file', $this->smarty->getTemplateDir(0), 'file')
, $tpl->getCached()->filepath);
$this->assertRegExp('/.*\/blar\/([a-f0-9]{2}\/){3}.*.php/', $tpl->getCached()->filepath);
}
/**
@@ -80,8 +75,7 @@ class CacheResourceFileTest extends CacheResourceTestCommon
$this->smarty->cache_lifetime = 1000;
$this->smarty->setUseSubDirs(true);
$tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
$this->assertEquals($this->buildCachedPath($tpl, true, 'foo|bar', 'blar', 'helloworld.tpl', $type = 'file', $this->smarty->getTemplateDir(0), 'file')
, $tpl->getCached()->filepath);
$this->assertRegExp('/.*\/foo\/bar\/blar\\/([a-f0-9]{2}\/){3}.*.php/', $tpl->getCached()->filepath);
}
/**

View File

@@ -362,12 +362,12 @@ abstract class CacheResourceTestCommon extends PHPUnit_Smarty
$this->assertEquals('something else 1', $tpl->getCachedContent());
$this->assertEquals('something else 2', $tpl2->getCachedContent());
$this->assertEquals('something else 3', $tpl3->getCachedContent());
sleep(10);
sleep(4);
$tpl4 = $this->smarty->createTemplate('helloworld2.tpl');
$tpl4->writeCachedContent('something else 4');
// test number of deleted caches
$this->doClearCacheAssertion(3,$this->smarty->clearAllCache(5));
$this->doClearCacheAssertion(3,$this->smarty->clearAllCache(2));
$tpl = $this->smarty->createTemplate('helloworld.tpl');
$tpl2 = $this->smarty->createTemplate('helloworld.tpl', null, 'bar');
@@ -422,7 +422,7 @@ abstract class CacheResourceTestCommon extends PHPUnit_Smarty
$this->smarty->cache_locking = true;
$this->smarty->locking_timeout = $lockTimeout;
}
$this->smarty->compile_id = $compile_id;
$this->smarty->setCompileId($compile_id);
$this->smarty->cache_id = $cache_id;
$this->smarty->force_compile = $forceCompile;
$this->smarty->force_cache = $forceCache;

View File

@@ -16,8 +16,8 @@ class Smarty_Resource_FiletestPlugin extends FilePlugin
{
parent::populate($source, $_template);
if ($source->exists) {
if (isset(CacheResourceTestCommon::$touchResource[$source->filepath])) {
$source->timestamp = CacheResourceTestCommon::$touchResource[$source->filepath];
if (isset(CacheResourceTestCommon::$touchResource[$source->getResourceName()])) {
$source->timestamp = CacheResourceTestCommon::$touchResource[$source->getResourceName()];
}
}
}

View File

@@ -31,7 +31,7 @@ class CompileCompilerPluginTest extends PHPUnit_Smarty
public function testCompilerPluginFunction()
{
$this->smarty->registerPlugin(\Smarty\Smarty::PLUGIN_COMPILER, 'compilerplugin', 'mycompilerplugin');
$this->smarty->compile_id = 'function';
$this->smarty->setCompileId('function');
$this->assertEquals("Hello World", $this->smarty->fetch('compilerplugintest.tpl'));
}
/**
@@ -40,7 +40,7 @@ class CompileCompilerPluginTest extends PHPUnit_Smarty
public function testCompilerPluginClassStatic()
{
$this->smarty->registerPlugin(\Smarty\Smarty::PLUGIN_COMPILER, 'compilerplugin', array('CompilerPluginClass', 'statCompile'));
$this->smarty->compile_id = 'static';
$this->smarty->setCompileId('static');
$this->assertEquals("Static World", $this->smarty->fetch('compilerplugintest.tpl'));
}
/**
@@ -50,7 +50,7 @@ class CompileCompilerPluginTest extends PHPUnit_Smarty
{
$plugin = new CompilerPluginClass;
$this->smarty->registerPlugin(\Smarty\Smarty::PLUGIN_COMPILER, 'compilerplugin', array($plugin, 'compile'));
$this->smarty->compile_id = 'object';
$this->smarty->setCompileId('object');
$this->assertEquals("Public World", $this->smarty->fetch('compilerplugintest.tpl'));
}
}

View File

@@ -35,7 +35,7 @@ class DefaultConfigHandlerTest extends PHPUnit_Smarty
public function testUnknownConfigFile()
{
$this->expectException(\Smarty\Exception::class);
$this->expectExceptionMessage('Unable to load config \'file:foo.conf\'');
$this->expectExceptionMessage('Unable to load \'file:foo.conf\'');
$this->smarty->configLoad('foo.conf');
}
@@ -79,7 +79,7 @@ class DefaultConfigHandlerTest extends PHPUnit_Smarty
public function testDefaultConfigHandlerReplacementByConfigFileFail()
{
$this->expectException(\Smarty\Exception::class);
$this->expectExceptionMessage("Unable to load config default file 'no.conf' for 'file:fo.conf'");
$this->expectExceptionMessage("Unable to load default file 'no.conf' for 'file:fo.conf'");
$this->smarty->registerDefaultConfigHandler('configHandlerFile');
$this->smarty->configLoad('fo.conf');
$this->assertEquals("123.4", $this->smarty->fetch('number.tpl'));
@@ -91,7 +91,7 @@ class DefaultConfigHandlerTest extends PHPUnit_Smarty
public function testDefaultConfigHandlerReplacementReturningFalse()
{
$this->expectException(\Smarty\Exception::class);
$this->expectExceptionMessage('Unable to load config \'file:foo.conf\'');
$this->expectExceptionMessage('Unable to load \'file:foo.conf\'');
$this->smarty->configLoad('foo.conf');
}

View File

@@ -45,7 +45,7 @@ class CustomResourceAmbiguousTest extends PHPUnit_Smarty
$resource_handler = new Smarty_Resource_AmbiguousPlugin(__DIR__ . '/templates/ambiguous/');
$this->smarty->registerResource('ambiguous', $resource_handler);
$this->smarty->setDefaultResourceType('ambiguous');
$this->smarty->setAllowAmbiguousResources(true);
// $this->smarty->setAllowAmbiguousResources(true);
$tpl = $this->smarty->createTemplate('foobar.tpl');
$this->assertFalse($tpl->getSource()->exists);
@@ -56,7 +56,7 @@ class CustomResourceAmbiguousTest extends PHPUnit_Smarty
$resource_handler = new Smarty_Resource_AmbiguousPlugin(__DIR__ . '/templates/ambiguous/');
$this->smarty->registerResource('ambiguous', $resource_handler);
$this->smarty->setDefaultResourceType('ambiguous');
$this->smarty->setAllowAmbiguousResources(true);
// $this->smarty->setAllowAmbiguousResources(true);
$resource_handler->setSegment('case1');
@@ -70,7 +70,7 @@ class CustomResourceAmbiguousTest extends PHPUnit_Smarty
$resource_handler = new Smarty_Resource_AmbiguousPlugin(__DIR__ . '/templates/ambiguous/');
$this->smarty->registerResource('ambiguous', $resource_handler);
$this->smarty->setDefaultResourceType('ambiguous');
$this->smarty->setAllowAmbiguousResources(true);
// $this->smarty->setAllowAmbiguousResources(true);
$resource_handler->setSegment('case2');
@@ -85,7 +85,7 @@ class CustomResourceAmbiguousTest extends PHPUnit_Smarty
$resource_handler = new Smarty_Resource_AmbiguousPlugin(__DIR__ . '/templates/ambiguous/');
$this->smarty->registerResource('ambiguous', $resource_handler);
$this->smarty->setDefaultResourceType('ambiguous');
$this->smarty->setAllowAmbiguousResources(true);
// $this->smarty->setAllowAmbiguousResources(true);
$resource_handler->setSegment('case1');
$tpl = $this->smarty->createTemplate('foobar.tpl');

View File

@@ -1,5 +1,6 @@
<?php
use Smarty\Exception;
use Smarty\Resource\FilePlugin;
use Smarty\Smarty;
use Smarty\Template;
@@ -40,11 +41,26 @@ class Smarty_Resource_AmbiguousPlugin extends FilePlugin
$segment = rtrim($this->segment, "/\\") . DIRECTORY_SEPARATOR;
}
$source->filepath = $this->directory . $segment . $source->name;
$source->uid = sha1($source->filepath);
$source->uid = sha1($segment . '#' . $source->getResourceName());
if ($_template->getSmarty()->getCompileCheck() && !isset($source->timestamp)) {
$source->timestamp = @filemtime($source->filepath);
$source->timestamp = @filemtime($this->directory . $segment . $source->name);
$source->exists = !!$source->timestamp;
}
}
public function getContent(Source $source) {
$segment = '';
if ($this->segment) {
$segment = rtrim($this->segment, "/\\") . DIRECTORY_SEPARATOR;
}
if ($source->exists) {
return file_get_contents($this->directory . $segment . $source->name);
}
throw new Exception(
'Unable to read ' . ($source->isConfig ? 'config' : 'template') .
" {$source->type} '{$source->name}'"
);
}
}

View File

@@ -117,7 +117,7 @@ if (MysqlResourceEnable == true) {
*/
public function testUnknownTemplate() {
$this->expectException(\Smarty\Exception::class);
$this->expectExceptionMessage('Unable to load template \'mysqlstest:foo.tpl\'');
$this->expectExceptionMessage('Unable to load \'mysqlstest:foo.tpl\'');
$this->assertEquals('foo', $this->smarty->fetch('mysqlstest:foo.tpl'));
}
}

View File

@@ -36,7 +36,7 @@ class DefaultTemplateHandlerTest extends PHPUnit_Smarty
$this->smarty->fetch('foo.tpl');
}
catch (Exception $e) {
$this->assertStringContainsString('Unable to load template', $e->getMessage());
$this->assertStringContainsString('Unable to load', $e->getMessage());
return;
}

View File

@@ -39,18 +39,12 @@ class EvalResourceTest extends PHPUnit_Smarty
$this->assertTrue($this->smarty->templateExists('eval:{$foo}'));
}
/**
* test getTemplateFilepath
*/
public function testGetTemplateFilepath()
public function testGetTemplateResourceName()
{
$tpl = $this->smarty->createTemplate('eval:hello world');
$this->assertEquals('2aae6c35c94fcfb415dbe95f408b9ce91ee846ed', $tpl->getSource()->filepath);
$this->assertEquals('hello world', $tpl->getSource()->getResourceName());
}
/**
* test getTemplateTimestamp
*/
public function testGetTemplateTimestamp()
{
$tpl = $this->smarty->createTemplate('eval:hello world');

View File

@@ -41,7 +41,7 @@ class ExtendsResourceTest extends PHPUnit_Smarty
$this->smarty->caching = $caching;
$this->smarty->merge_compiled_includes = $merge;
if ($merge) {
$this->smarty->compile_id = 1;
$this->smarty->setCompileId(1);
}
$result = $this->smarty->fetch('extends:003_parent.tpl|003_child_prepend.tpl');
$this->assertStringContainsString(
@@ -64,7 +64,7 @@ class ExtendsResourceTest extends PHPUnit_Smarty
$this->smarty->caching = $caching;
$this->smarty->merge_compiled_includes = $merge;
if ($merge) {
$this->smarty->compile_id = 1;
$this->smarty->setCompileId(1);
}
$result = $this->smarty->fetch('extends:004_parent.tpl|004_child_append.tpl');
$this->assertStringContainsString("Default Title - append", $result, $testName . ' - content');
@@ -82,7 +82,7 @@ class ExtendsResourceTest extends PHPUnit_Smarty
$this->smarty->caching = $caching;
$this->smarty->merge_compiled_includes = $merge;
if ($merge) {
$this->smarty->compile_id = 1;
$this->smarty->setCompileId(1);
}
$result = $this->smarty->fetch('extends:040_parent.tpl|040_child.tpl');
$this->assertStringContainsString("var-bar-var", $result, $testName . ' - content');
@@ -99,7 +99,7 @@ class ExtendsResourceTest extends PHPUnit_Smarty
$this->smarty->caching = $caching;
$this->smarty->merge_compiled_includes = $merge;
if ($merge) {
$this->smarty->compile_id = 1;
$this->smarty->setCompileId(1);
}
$result = $this->smarty->fetch('extends:050_parent.tpl|050_child.tpl|050_grandchild.tpl');
$this->assertStringContainsString("var-bar-var", $result, $testName . ' - content');

View File

@@ -38,10 +38,10 @@ class FileResourceTest extends PHPUnit_Smarty
/**
*
*/
public function testGetTemplateFilepath()
public function testGetTemplateResourceName()
{
$tpl = $this->smarty->createTemplate('helloworld.tpl');
$this->assertEquals($this->normalizePath("./templates/helloworld.tpl"), $tpl->getSource()->filepath);
$this->assertEquals('helloworld.tpl', $tpl->getSource()->getResourceName());
}
public function testTemplateFileExists1()
@@ -102,14 +102,6 @@ class FileResourceTest extends PHPUnit_Smarty
$this->assertFalse($tpl->getSource()->handler->recompiled);
}
public function testGetCompiledFilepath()
{
$tpl = $this->smarty->createTemplate('helloworld.tpl');
$this->assertEquals($this->buildCompiledPath($tpl, false, false, null, 'helloworld.tpl', 'file', $this->smarty->getTemplateDir(0))
, $tpl->getCompiled()->filepath
);
}
/**
* @doesNotPerformAssertions
*/
@@ -152,8 +144,8 @@ class FileResourceTest extends PHPUnit_Smarty
{
// touch to prepare next test
sleep(2);
$tpl = $this->smarty->createTemplate('helloworld.tpl');
touch($tpl->getSource()->filepath);
$this->smarty->createTemplate('helloworld.tpl');
touch(__DIR__ . '/templates/helloworld.tpl');
$this->setUp();
@@ -170,26 +162,23 @@ class FileResourceTest extends PHPUnit_Smarty
$this->assertTrue(file_exists($tpl->getCompiled()->filepath));
}
public function testGetCachedFilepath()
{
$this->smarty->caching = true;
$this->smarty->cache_lifetime = 1000;
$tpl = $this->smarty->createTemplate('helloworld.tpl');
$this->assertEquals($this->buildCachedPath($tpl, false, null, null, 'helloworld.tpl', 'file', $this->smarty->getTemplateDir(0), 'file')
, $tpl->getCached()->filepath
);
}
public function testGetCachedTimestamp()
{
// create dummy cache file for the following test
file_put_contents($this->buildCachedPath($this->smarty, false, null, null, 'helloworld.tpl', 'file', $this->smarty->getTemplateDir(0), 'file')
, '<?php ?>');
$this->smarty->caching = true;
$this->smarty->cache_lifetime = 1000;
$this->smarty->caching = true;
$this->smarty->cache_lifetime = 1000;
$tpl = $this->smarty->createTemplate('helloworld.tpl');
$tpl->fetch();
$timestamp = $tpl->getCached()->timestamp;
$this->smarty = new \Smarty\Smarty();
$this->smarty->caching = true;
$this->smarty->cache_lifetime = 1000;
$tpl = $this->smarty->createTemplate('helloworld.tpl');
$this->assertTrue(is_integer($tpl->getCached()->timestamp));
$this->assertEquals(10, strlen($tpl->getCached()->timestamp));
$this->assertEquals($timestamp, $tpl->getCached()->timestamp);
}

View File

@@ -25,30 +25,6 @@ class FileResourceIndexedTest extends PHPUnit_Smarty
$this->cleanDirs();
}
public function testGetTemplateFilepath()
{
$tpl = $this->smarty->createTemplate('dirname.tpl');
$this->assertEquals($this->normalizePath("./templates/dirname.tpl"), $tpl->getSource()->filepath);
}
public function testGetTemplateFilepathNumber()
{
$tpl = $this->smarty->createTemplate('[1]dirname.tpl');
$this->assertEquals($this->normalizePath('./templates_2/dirname.tpl'), $tpl->getSource()->filepath);
}
public function testGetTemplateFilepathNumeric()
{
$tpl = $this->smarty->createTemplate('[10]dirname.tpl');
$this->assertEquals($this->normalizePath('./templates_3/dirname.tpl'), $tpl->getSource()->filepath);
}
public function testGetTemplateFilepathName()
{
$tpl = $this->smarty->createTemplate('[foo]dirname.tpl');
$this->assertEquals($this->normalizePath('./templates_4/dirname.tpl'), $tpl->getSource()->filepath);
}
public function testFetch()
{
$tpl = $this->smarty->createTemplate('dirname.tpl');
@@ -101,15 +77,18 @@ class FileResourceIndexedTest extends PHPUnit_Smarty
public function testGetCompiledFilepath()
{
$tpl = $this->smarty->createTemplate('[foo]dirname.tpl');
$this->assertEquals($this->buildCompiledPath($tpl, false, false, null, 'dirname.tpl', 'file', $this->smarty->getTemplateDir('foo')), $tpl->getCompiled()->filepath);
$tpl2 = $this->smarty->createTemplate('dirname.tpl');
$this->assertNotEquals($tpl->getCompiled()->filepath, $tpl2->getCompiled()->filepath);
}
public function testGetCachedFilepath()
{
$this->smarty->caching = true;
$this->smarty->cache_lifetime = 1000;
$tpl = $this->smarty->createTemplate('[foo]dirname.tpl');
$this->assertEquals($this->buildCachedPath($tpl, false, null, null, 'dirname.tpl', 'file', $this->smarty->getTemplateDir('foo'))
, $tpl->getCached()->filepath);
$tpl = $this->smarty->createTemplate('[foo]dirname.tpl');
$tpl2 = $this->smarty->createTemplate('dirname.tpl');
$this->assertNotEquals($tpl->getCached()->filepath, $tpl2->getCached()->filepath);
}
}

View File

@@ -59,10 +59,10 @@ class RegisteredResourceTest extends PHPUnit_Smarty
public function testResourceCompileIdChange()
{
$this->smarty->registerResource('myresource', new RegisteredResourceTest_Resource2Plugin());
$this->smarty->compile_id = 'a';
$this->smarty->setCompileId('a');
$this->assertEquals('this is template 1', $this->smarty->fetch('myresource:some'));
$this->assertEquals('this is template 1', $this->smarty->fetch('myresource:some'));
$this->smarty->compile_id = 'b';
$this->smarty->setCompileId('b');
$this->assertEquals('this is template 2', $this->smarty->fetch('myresource:some'));
$this->assertEquals('this is template 2', $this->smarty->fetch('myresource:some'));
}

View File

@@ -17,7 +17,6 @@ use Smarty\Template\Source;
class Smarty_Resource_Db extends RecompiledPlugin {
public function populate(Source $source, Template $_template = null) {
$source->filepath = 'db:';
$source->uid = sha1($source->resource);
$source->timestamp = 1000000000;
$source->exists = true;

View File

@@ -18,7 +18,6 @@ class Smarty_Resource_Db2 extends RecompiledPlugin
{
public function populate(Source $source, Template $_template = null)
{
$source->filepath = 'db2:';
$source->uid = sha1($source->resource);
$source->timestamp = 0;
$source->exists = true;

View File

@@ -17,7 +17,6 @@ class Smarty_Resource_Db3 extends Smarty\Resource\BasePlugin
{
public function populate(Source $source, Template $_template = null)
{
$source->filepath = 'db3:';
$source->uid = sha1($source->resource);
$source->timestamp = 0;
$source->exists = true;

View File

@@ -18,7 +18,6 @@ class Smarty_Resource_Db4 extends Smarty\Resource\BasePlugin
{
public function populate(Source $source, Template $_template = null)
{
$source->filepath = 'db4:';
$source->uid = sha1($source->resource);
$source->timestamp = 0;
$source->exists = true;

View File

@@ -40,10 +40,10 @@ class StreamResourceTest extends PHPUnit_Smarty
/**
* test getTemplateFilepath
*/
public function testGetTemplateFilepath()
public function testGetFullResourceName()
{
$tpl = $this->smarty->createTemplate('global:mytest');
$this->assertEquals('global://mytest', $tpl->getSource()->filepath);
$this->assertEquals('global:mytest', $tpl->getSource()->getFullResourceName());
}
/**

View File

@@ -56,7 +56,7 @@ class StringResourceTest extends PHPUnit_Smarty
public function testGetTemplateFilepath()
{
$tpl = $this->smarty->createTemplate('string:hello world');
$this->assertEquals($this->buildSourcePath($tpl), $tpl->getSource()->filepath);
$this->assertEquals('hello world', $tpl->getSource()->getResourceName());
}
/**
@@ -104,15 +104,6 @@ class StringResourceTest extends PHPUnit_Smarty
$this->assertTrue($tpl->mustCompile());
}
/**
* test getCompiledFilepath
*/
public function testGetCompiledFilepath()
{
$tpl = $this->smarty->createTemplate('string:hello world');
$this->assertEquals($this->buildCompiledPath($tpl, false, false, null, 'hello world', 'string', $this->smarty->getTemplateDir(0)), $tpl->getCompiled()->filepath);
}
/**
* test getCompiledTimestamp
*/

View File

@@ -272,7 +272,7 @@ class SecurityTest extends PHPUnit_Smarty
*/
public function testTemplateTrustedStream()
{
stream_wrapper_register("global", "ResourceStreamSecurity")
stream_wrapper_register("global", ResourceStreamSecurity::class)
or die("Failed to register protocol");
$fp = fopen("global://mytest", "r+");
fwrite($fp, 'hello world {$foo}');
@@ -291,7 +291,7 @@ class SecurityTest extends PHPUnit_Smarty
{
$this->expectException(\Smarty\Exception::class);
$this->expectExceptionMessage('stream \'global\' not allowed by security setting');
stream_wrapper_register("global", "ResourceStreamSecurity")
stream_wrapper_register("global", ResourceStreamSecurity::class)
or die("Failed to register protocol");
$fp = fopen("global://mytest", "r+");
fwrite($fp, 'hello world {$foo}');

View File

@@ -16,12 +16,10 @@
*/
class ClearCompiledTest extends PHPUnit_Smarty
{
public $methodName = null;
public function setUp(): void
{
$this->setUpSmarty(__DIR__);
$this->smarty->addTemplateDir('./templates_2/');
$this->methodName = 'clearCompiledTemplate';
}
@@ -165,7 +163,7 @@ class ClearCompiledTest extends PHPUnit_Smarty
$this->makeFiles();
$expected = array();
$this->assertEquals(12, $this->getSmarty()->{$this->methodName}());
$this->assertEquals(12, $this->getSmarty()->clearCompiledTemplate());
$this->assertEquals($this->expectFiles($expected), $this->getFiles());
$this->clearFiles();
@@ -203,7 +201,7 @@ class ClearCompiledTest extends PHPUnit_Smarty
'ambiguous/case1/foobar.tpl#', 'ambiguous/case1/foobar.tpl#compile1', 'ambiguous/case1/foobar.tpl#compile2',
'[1]ambiguous/case1/foobar.tpl#', '[1]ambiguous/case1/foobar.tpl#compile1', '[1]ambiguous/case1/foobar.tpl#compile2',
);
$this->assertEquals(3, $this->getSmarty()->{$this->methodName}('helloworld.tpl'));
$this->assertEquals(3, $this->getSmarty()->clearCompiledTemplate('helloworld.tpl'));
$this->assertEquals($this->expectFiles($expected), $this->getFiles());
$this->clearFiles();
@@ -216,7 +214,7 @@ class ClearCompiledTest extends PHPUnit_Smarty
$this->makeFiles();
$expected = array_keys($this->_files);
$this->assertEquals(0, $this->getSmarty()->{$this->methodName}('foobar.tpl'));
$this->assertEquals(0, $this->getSmarty()->clearCompiledTemplate('foobar.tpl'));
$this->assertEquals($this->expectFiles($expected), $this->getFiles());
$this->clearFiles();
@@ -255,7 +253,7 @@ class ClearCompiledTest extends PHPUnit_Smarty
'ambiguous/case1/foobar.tpl#', 'ambiguous/case1/foobar.tpl#compile2',
'[1]ambiguous/case1/foobar.tpl#', '[1]ambiguous/case1/foobar.tpl#compile2',
);
$count = $this->getSmarty()->{$this->methodName}(null, 'compile1');
$count = $this->getSmarty()->clearCompiledTemplate(null, 'compile1');
$this->assertEquals(4, $count);
$this->assertEquals($this->expectFiles($expected), $this->getFiles());
@@ -269,7 +267,7 @@ class ClearCompiledTest extends PHPUnit_Smarty
$this->makeFiles();
$expected = array_keys($this->_files);
$this->assertEquals(0, $this->getSmarty()->{$this->methodName}(null, 'other'));
$this->assertEquals(0, $this->getSmarty()->clearCompiledTemplate(null, 'other'));
$this->assertEquals($this->expectFiles($expected), $this->getFiles());
$this->clearFiles();
@@ -294,7 +292,7 @@ class ClearCompiledTest extends PHPUnit_Smarty
$expected = array('helloworld.tpl#', 'helloworld2.tpl#');
$this->touchFiles(array_diff(array_keys($this->_files), $expected), - 1000);
$this->assertEquals(10, $this->getSmarty()->{$this->methodName}(null, null, 500));
$this->assertEquals(10, $this->getSmarty()->clearCompiledTemplate(null, null, 500));
$this->assertEquals($this->expectFiles($expected), $this->getFiles());
$this->clearFiles();
@@ -324,7 +322,7 @@ class ClearCompiledTest extends PHPUnit_Smarty
'[1]ambiguous/case1/foobar.tpl#', '[1]ambiguous/case1/foobar.tpl#compile1', '[1]ambiguous/case1/foobar.tpl#compile2',
);
$this->touchFiles(array('helloworld.tpl#compile1'), - 1000);
$this->assertEquals(1, $this->getSmarty()->{$this->methodName}("helloworld.tpl", null, 500));
$this->assertEquals(1, $this->getSmarty()->clearCompiledTemplate("helloworld.tpl", null, 500));
$this->assertEquals($this->expectFiles($expected), $this->getFiles());
$this->clearFiles();
@@ -354,7 +352,7 @@ class ClearCompiledTest extends PHPUnit_Smarty
'[1]ambiguous/case1/foobar.tpl#', '[1]ambiguous/case1/foobar.tpl#compile1', '[1]ambiguous/case1/foobar.tpl#compile2',
);
$this->touchFiles(array('helloworld.tpl#compile1', 'helloworld.tpl#compile2'), - 1000);
$this->assertEquals(1, $this->getSmarty()->{$this->methodName}("helloworld.tpl", "compile1", 500));
$this->assertEquals(1, $this->getSmarty()->clearCompiledTemplate("helloworld.tpl", "compile1", 500));
$this->assertEquals($this->expectFiles($expected), $this->getFiles());
$this->clearFiles();
@@ -384,7 +382,7 @@ class ClearCompiledTest extends PHPUnit_Smarty
'[1]ambiguous/case1/foobar.tpl#', '[1]ambiguous/case1/foobar.tpl#compile1', '[1]ambiguous/case1/foobar.tpl#compile2',
);
$this->touchFiles(array('helloworld.tpl#compile1'), - 1000);
$this->assertEquals(1, $this->getSmarty()->{$this->methodName}(null, "compile1", 500));
$this->assertEquals(1, $this->getSmarty()->clearCompiledTemplate(null, "compile1", 500));
$this->assertEquals($this->expectFiles($expected), $this->getFiles());
$this->clearFiles();
@@ -413,7 +411,7 @@ class ClearCompiledTest extends PHPUnit_Smarty
'ambiguous/case1/foobar.tpl#', 'ambiguous/case1/foobar.tpl#compile1', 'ambiguous/case1/foobar.tpl#compile2',
'[1]ambiguous/case1/foobar.tpl#', '[1]ambiguous/case1/foobar.tpl#compile1', '[1]ambiguous/case1/foobar.tpl#compile2',
);
$this->assertEquals(1, $this->getSmarty()->{$this->methodName}("helloworld.tpl", "compile1"));
$this->assertEquals(1, $this->getSmarty()->clearCompiledTemplate("helloworld.tpl", "compile1"));
$this->assertEquals($this->expectFiles($expected), $this->getFiles());
$this->clearFiles();
@@ -443,7 +441,7 @@ class ClearCompiledTest extends PHPUnit_Smarty
'helloworld2.tpl#', 'helloworld2.tpl#compile1', 'helloworld2.tpl#compile2',
'[1]ambiguous/case1/foobar.tpl#', '[1]ambiguous/case1/foobar.tpl#compile1', '[1]ambiguous/case1/foobar.tpl#compile2',
);
$this->assertEquals(3, $this->getSmarty()->{$this->methodName}("ambiguous/case1/foobar.tpl"));
$this->assertEquals(3, $this->getSmarty()->clearCompiledTemplate("ambiguous/case1/foobar.tpl"));
$this->assertEquals($this->expectFiles($expected), $this->getFiles());
$this->clearFiles();

View File

@@ -0,0 +1,139 @@
<?php
/**
* Smarty PHPunit tests for compile check
*/
class CompileCheckTest extends PHPUnit_Smarty
{
public function setUp(): void
{
$this->setUpSmarty(__DIR__);
$this->smarty->addTemplateDir('./templates_tmp');
$this->cleanDirs();
}
/**
* generate templates
*/
protected function makeFiles()
{
file_put_contents('./templates_tmp/t1.tpl', 'TPL1');
file_put_contents('./templates_tmp/t2.tpl', 'TPL2');
file_put_contents('./templates_tmp/base.tpl', '{include file="t1.tpl"}{include file="t2.tpl"}');
}
/**
* remove generated templates
*/
protected function removeFiles()
{
unlink('./templates_tmp/t1.tpl');
unlink('./templates_tmp/t2.tpl');
unlink('./templates_tmp/base.tpl');
}
/**
* reset, but leave the files alone
* @return void
*/
private function softResetSmarty() {
$this->smarty = new \Smarty\Smarty();
$this->smarty->addTemplateDir('./templates_tmp');
}
/**
* @group slow
*/
public function testCompileCheckOn0()
{
$this->makeFiles();
$this->assertEquals('TPL1TPL2', $this->smarty->fetch('base.tpl'));
$this->softResetSmarty();
$this->smarty->setCompileCheck(\Smarty\Smarty::COMPILECHECK_ON);
$this->assertEquals('TPL1TPL2', $this->smarty->fetch('base.tpl'));
}
/**
* @group slow
*/
public function testCompileCheckOn1()
{
$this->makeFiles();
$this->assertEquals('TPL1TPL2', $this->smarty->fetch('base.tpl'));
$this->softResetSmarty();
$this->smarty->setCompileCheck(\Smarty\Smarty::COMPILECHECK_ON);
unlink('./templates_tmp/base.tpl');
sleep(1);
$this->expectException(\Smarty\Exception::class);
$this->smarty->fetch('base.tpl');
}
/**
* @group slow
*/
public function testCompileCheckOn2()
{
$this->makeFiles();
$this->assertEquals('TPL1TPL2', $this->smarty->fetch('base.tpl'));
$this->softResetSmarty();
$this->smarty->setCompileCheck(\Smarty\Smarty::COMPILECHECK_ON);
sleep(1);
file_put_contents('./templates_tmp/base.tpl', 'hello');
$this->assertEquals('hello', $this->smarty->fetch('base.tpl'));
}
/**
* @group slow
*/
public function testCompileCheckOff0()
{
$this->makeFiles();
$this->assertEquals('TPL1TPL2', $this->smarty->fetch('base.tpl'));
$this->softResetSmarty();
$this->smarty->setCompileCheck(\Smarty\Smarty::COMPILECHECK_OFF);
$this->assertEquals('TPL1TPL2', $this->smarty->fetch('base.tpl'));
}
/**
* @group slow
*/
public function testCompileCheckOff1()
{
$this->makeFiles();
$this->assertEquals('TPL1TPL2', $this->smarty->fetch('base.tpl'));
$this->softResetSmarty();
$this->smarty->setCompileCheck(\Smarty\Smarty::COMPILECHECK_OFF);
unlink('./templates_tmp/base.tpl');
sleep(1);
$this->assertEquals('TPL1TPL2', $this->smarty->fetch('base.tpl'));
}
/**
* @group slow
*/
public function testCompileCheckOff2()
{
$this->makeFiles();
$this->assertEquals('TPL1TPL2', $this->smarty->fetch('base.tpl'));
$this->softResetSmarty();
$this->smarty->setCompileCheck(\Smarty\Smarty::COMPILECHECK_OFF);
sleep(1);
file_put_contents('./templates_tmp/base.tpl', 'hello');
$this->assertEquals('TPL1TPL2', $this->smarty->fetch('base.tpl'));
}
}

View File

@@ -209,7 +209,7 @@ class CompileBlockPluginTest extends PHPUnit_Smarty
{
$this->smarty->registerFilter('pre', array($this, 'prefilterTest'));
$this->smarty->registerPlugin(\Smarty\Smarty::PLUGIN_BLOCK, 'cachetest', 'myblockplugintest2', $cachable);
$this->smarty->compile_id = $compileid;
$this->smarty->setCompileId($compileid);
$this->smarty->caching = $caching;
$this->smarty->cache_lifetime = 1000;
$this->smarty->assign('test', $testNumber);
@@ -292,7 +292,7 @@ class CompileBlockPluginTest extends PHPUnit_Smarty
$this->makeTemplateFile($file, $code);
$this->smarty->setTemplateDir('./templates_tmp');
$this->smarty->registerDefaultPluginHandler('my_block_plugin_handler');
$this->smarty->compile_id='default';
$this->smarty->setCompileId('default');
$this->smarty->assign('foo', 'bar');
$this->assertEquals($result,
$this->smarty->fetch($file),

View File

@@ -35,7 +35,7 @@ class My_Resource_Extendsall extends \Smarty\Resource\ExtendsPlugin
continue;
}
$sources[ $s->uid ] = $s;
$uid .= $s->filepath;
$uid .= $s->uid;
$timestamp = $s->timestamp > $timestamp ? $s->timestamp : $timestamp;
} catch (Exception $e) {
}
@@ -48,7 +48,6 @@ class My_Resource_Extendsall extends \Smarty\Resource\ExtendsPlugin
reset($sources);
$s = current($sources);
$source->components = $sources;
$source->filepath = $s->filepath;
$source->uid = sha1($uid . $source->getSmarty()->_joined_template_dir);
$source->exists = true;
$source->timestamp = $timestamp;