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,10 +321,6 @@ 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;
}
@@ -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

@@ -48,17 +48,16 @@ abstract class CustomPlugin extends BasePlugin {
* 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;
@@ -27,22 +28,23 @@ class FilePlugin extends BasePlugin {
* 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) {
if (isset($source->getSmarty()->security_policy) && is_object($source->getSmarty()->security_policy)) {
$source->getSmarty()->security_policy->isTrustedResourceDir($source->filepath, $source->isConfig);
}
$source->exists = true;
$source->uid = sha1(
$source->filepath . ($source->isConfig ? $source->getSmarty()->_joined_config_dir :
$source->name . ($source->isConfig ? $source->getSmarty()->_joined_config_dir :
$source->getSmarty()->_joined_template_dir)
);
$source->timestamp = filemtime($source->filepath);
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($path, $source->isConfig);
}
$source->exists = true;
$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

@@ -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}'");
}
}

View File

@@ -48,8 +48,8 @@ use Smarty\Smarty\Runtime\TplFunctionRuntime;
/**
* This is the main Smarty class
*/
class Smarty extends \Smarty\TemplateBase
{
class Smarty extends \Smarty\TemplateBase {
/**
* smarty version
*/
@@ -198,13 +198,6 @@ class Smarty extends \Smarty\TemplateBase
*/
public $use_sub_dirs = false;
/**
* allow ambiguous resources (that are made unique by the resource handler)
*
* @var boolean
*/
private $allow_ambiguous_resources = false;
/**
* merge compiled includes
*
@@ -238,7 +231,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @var array string
*/
public $literals = array();
public $literals = [];
/**
* class name
@@ -375,35 +368,35 @@ class Smarty extends \Smarty\TemplateBase
*
* @var array
*/
public $registered_plugins = array();
public $registered_plugins = [];
/**
* registered objects
*
* @var array
*/
public $registered_objects = array();
public $registered_objects = [];
/**
* registered classes
*
* @var array
*/
public $registered_classes = array();
public $registered_classes = [];
/**
* registered filters
*
* @var array
*/
public $registered_filters = array();
public $registered_filters = [];
/**
* registered resources
*
* @var array
*/
public $registered_resources = array();
public $registered_resources = [];
/**
* registered cache resources
@@ -411,14 +404,14 @@ class Smarty extends \Smarty\TemplateBase
* @var array
* @deprecated since 5.0
*/
private $registered_cache_resources = array();
private $registered_cache_resources = [];
/**
* default modifier
*
* @var array
*/
public $default_modifiers = array();
public $default_modifiers = [];
/**
* autoescape variable output
@@ -434,13 +427,6 @@ class Smarty extends \Smarty\TemplateBase
*/
public $start_time = 0;
/**
* required by the compiler for BC
*
* @var string
*/
public $_current_file = null;
/**
* internal flag to enable parser debugging
*
@@ -460,28 +446,28 @@ class Smarty extends \Smarty\TemplateBase
*
* @var array
*/
protected $template_dir = array('./templates/');
protected $template_dir = ['./templates/'];
/**
* flags for normalized template directory entries
*
* @var array
*/
protected $_processedTemplateDir = array();
protected $_processedTemplateDir = [];
/**
* config directory
*
* @var array
*/
protected $config_dir = array('./configs/');
protected $config_dir = ['./configs/'];
/**
* flags for normalized template directory entries
*
* @var array
*/
protected $_processedConfigDir = array();
protected $_processedConfigDir = [];
/**
* compile directory
@@ -499,24 +485,28 @@ class Smarty extends \Smarty\TemplateBase
/**
* PHP7 Compatibility mode
*
* @var bool
*/
private $isMutingUndefinedOrNullWarnings = false;
/**
* Cache of loaded resource handlers.
*
* @var array
*/
public $_resource_handlers = [];
/**
* Cache of loaded cacheresource handlers.
*
* @var array
*/
public $_cacheresource_handlers = [];
/**
* List of extensions
*
* @var ExtensionInterface[]
*/
private $extensions = [];
@@ -528,8 +518,7 @@ class Smarty extends \Smarty\TemplateBase
/**
* Initialize new Smarty object
*/
public function __construct()
{
public function __construct() {
$this->start_time = microtime(true);
// Check if we're running on Windows
@@ -568,8 +557,6 @@ class Smarty extends \Smarty\TemplateBase
return $this->extensions;
}
/**
* Check if a template resource exists
*
@@ -578,8 +565,7 @@ class Smarty extends \Smarty\TemplateBase
* @return bool status
* @throws \Smarty\Exception
*/
public function templateExists($resource_name)
{
public function templateExists($resource_name) {
// create source object
$source = Template\Source::load(null, $this, $resource_name);
return $source->exists;
@@ -593,8 +579,7 @@ class Smarty extends \Smarty\TemplateBase
* @return Smarty current Smarty instance for chaining
* @throws \Smarty\Exception
*/
public function enableSecurity($security_class = null)
{
public function enableSecurity($security_class = null) {
\Smarty\Security::enableSecurity($this, $security_class);
return $this;
}
@@ -604,8 +589,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return Smarty current Smarty instance for chaining
*/
public function disableSecurity()
{
public function disableSecurity() {
$this->security_policy = null;
return $this;
}
@@ -619,8 +603,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return Smarty current Smarty instance for chaining
*/
public function addTemplateDir($template_dir, $key = null, $isConfig = false)
{
public function addTemplateDir($template_dir, $key = null, $isConfig = false) {
if ($isConfig) {
$processed = &$this->_processedConfigDir;
$dir = &$this->config_dir;
@@ -662,8 +645,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return array|string list of template directories, or directory of $index
*/
public function getTemplateDir($index = null, $isConfig = false)
{
public function getTemplateDir($index = null, $isConfig = false) {
if ($isConfig) {
$dir = &$this->config_dir;
} else {
@@ -686,14 +668,13 @@ class Smarty extends \Smarty\TemplateBase
*
* @return Smarty current Smarty instance for chaining
*/
public function setTemplateDir($template_dir, $isConfig = false)
{
public function setTemplateDir($template_dir, $isConfig = false) {
if ($isConfig) {
$this->config_dir = array();
$this->_processedConfigDir = array();
$this->config_dir = [];
$this->_processedConfigDir = [];
} else {
$this->template_dir = array();
$this->_processedTemplateDir = array();
$this->template_dir = [];
$this->_processedTemplateDir = [];
}
$this->addTemplateDir($template_dir, null, $isConfig);
return $this;
@@ -707,8 +688,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return Smarty current Smarty instance for chaining
*/
public function addConfigDir($config_dir, $key = null)
{
public function addConfigDir($config_dir, $key = null) {
return $this->addTemplateDir($config_dir, $key, true);
}
@@ -719,8 +699,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return array configuration directory
*/
public function getConfigDir($index = null)
{
public function getConfigDir($index = null) {
return $this->getTemplateDir($index, true);
}
@@ -731,12 +710,10 @@ class Smarty extends \Smarty\TemplateBase
*
* @return Smarty current Smarty instance for chaining
*/
public function setConfigDir($config_dir)
{
public function setConfigDir($config_dir) {
return $this->setTemplateDir($config_dir, true);
}
/**
* Registers plugin to be used in templates
*
@@ -811,8 +788,7 @@ class Smarty extends \Smarty\TemplateBase
* @return Smarty current Smarty instance for chaining
* @deprecated since 5.0
*/
public function addPluginsDir($plugins_dir)
{
public function addPluginsDir($plugins_dir) {
trigger_error('Using Smarty::addPluginsDir() to load plugins is deprecated and will be ' .
'removed in a future release. Use Smarty::addExtension() to add an extension or Smarty::registerPlugin to ' .
'quickly register a plugin using a callback function.', E_USER_DEPRECATED);
@@ -831,14 +807,12 @@ class Smarty extends \Smarty\TemplateBase
* @return array list of plugin directories
* @deprecated since 5.0
*/
public function getPluginsDir()
{
public function getPluginsDir() {
trigger_error('Using Smarty::getPluginsDir() is deprecated and will be ' .
'removed in a future release. It will always return an empty array.', E_USER_DEPRECATED);
return [];
}
/**
* Set plugins directory
*
@@ -847,8 +821,7 @@ class Smarty extends \Smarty\TemplateBase
* @return Smarty current Smarty instance for chaining
* @deprecated since 5.0
*/
public function setPluginsDir($plugins_dir)
{
public function setPluginsDir($plugins_dir) {
trigger_error('Using Smarty::getPluginsDir() is deprecated and will be ' .
'removed in a future release. For now, it will remove the DefaultExtension from the extensions list and ' .
'proceed to call Smartyy::addPluginsDir..', E_USER_DEPRECATED);
@@ -890,14 +863,12 @@ class Smarty extends \Smarty\TemplateBase
return $this;
}
/**
* Get compiled directory
*
* @return string path to compiled templates
*/
public function getCompileDir()
{
public function getCompileDir() {
if (!$this->_compileDirNormalized) {
$this->_normalizeDir('compile_dir', $this->compile_dir);
$this->_compileDirNormalized = true;
@@ -911,8 +882,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return Smarty current Smarty instance for chaining
*/
public function setCompileDir($compile_dir)
{
public function setCompileDir($compile_dir) {
$this->_normalizeDir('compile_dir', $compile_dir);
$this->_compileDirNormalized = true;
return $this;
@@ -923,8 +893,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return string path of cache directory
*/
public function getCacheDir()
{
public function getCacheDir() {
if (!$this->_cacheDirNormalized) {
$this->_normalizeDir('cache_dir', $this->cache_dir);
$this->_cacheDirNormalized = true;
@@ -939,8 +908,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return Smarty current Smarty instance for chaining
*/
public function setCacheDir($cache_dir)
{
public function setCacheDir($cache_dir) {
$this->_normalizeDir('cache_dir', $cache_dir);
$this->_cacheDirNormalized = true;
return $this;
@@ -951,23 +919,17 @@ class Smarty extends \Smarty\TemplateBase
/**
* Creates a template object
*
* @param Template|null $template_name
* @param string $template_name
* @param mixed $cache_id cache id to be used with this template
* @param mixed $compile_id compile id to be used with this template
* @param null $parent next higher level of Smarty variables
* @param null $caching
* @param null $cache_lifetime
* @param string|null $baseFilePath
* @param bool $isConfig
*
* @return Template template object
* @throws Exception
*/
public function createTemplate($template_name, $cache_id = null, $compile_id = null, $parent = null, $caching = null,
$cache_lifetime = null, string $baseFilePath = null, bool $isConfig = false)
{
public function createTemplate($template_name, $cache_id = null, $compile_id = null, $parent = null): Template {
$data = null;
$data = [];
// Shuffle params for backward compatibility: if 2nd param is an object, it's the parent
if (is_object($cache_id)) {
@@ -981,98 +943,43 @@ class Smarty extends \Smarty\TemplateBase
$cache_id = null;
}
if (!$this->_templateDirNormalized) {
$this->_normalizeTemplateConfig(false);
}
$_templateId = $this->generateUniqueTemplateId($template_name, $cache_id, $compile_id, $caching, $baseFilePath);
if (!isset($this->templates[$_templateId])) {
$newTemplate = new Template($template_name, $this, $parent ?: $this, $cache_id, $compile_id, $caching, $isConfig);
$newTemplate->templateId = $_templateId; // @TODO this could go in constructor ^?
$this->templates[$_templateId] = $newTemplate;
}
$tpl = clone $this->templates[$_templateId];
// If $this->allow_ambiguous_resources, the context of the section is different each time
if ($this->allow_ambiguous_resources || $tpl->getParent() !== ($parent ?: $this)) {
$tpl->setParent($parent ?: $this);
}
if ($cache_lifetime) {
$tpl->setCacheLifetime($cache_lifetime);
}
// fill data if present
if (!empty($data) && is_array($data)) {
// set up variable values
foreach ($data as $_key => $_val) {
$tpl->assign($_key, $_val);
}
}
$tpl->tplFunctions = array_merge($parent->tplFunctions ?? [], $tpl->tplFunctions ?? []);
if (!$this->debugging && $this->debugging_ctrl === 'URL') {
$tpl->getSmarty()->getDebug()->debugUrl($tpl->getSmarty());
}
return $tpl;
return $this->doCreateTemplate($template_name, $cache_id, $compile_id, $parent, null, null, false, $data);
}
/**
* Get unique template id
*
* @param string $template_name
* @param string $resource_name
* @param null|mixed $cache_id
* @param null|mixed $compile_id
* @param null $caching
* @param string|null $baseFilePath
*
* @return string
*/
private function generateUniqueTemplateId(
$template_name,
$resource_name,
$cache_id = null,
$compile_id = null,
$caching = null,
string $baseFilePath = null
$caching = null
): string {
// defaults for optional params
$cache_id = $cache_id ?? $this->cache_id;
$compile_id = $compile_id ?? $this->compile_id;
$caching = (int)$caching ?? $this->caching;
if (strpos($template_name, ':') === false) {
$template_name = "{$this->default_resource_type}:{$template_name}";
// Add default resource type to resource name if it is missing
if (strpos($resource_name, ':') === false) {
$resource_name = "{$this->default_resource_type}:{$resource_name}";
}
$id_parts = [];
[$name, $type] = BasePlugin::parseResourceName($template_name, $this->default_resource_type);
$nameIsDotted = !empty($name) && $name[0] === '.' && ($name[1] === '.' || $name[1] === '/');
$id_parts[] = $type;
$id_parts[] = $this->getSmarty()->_joined_template_dir;
// handle relative template names
if ($baseFilePath && $nameIsDotted) {
// go relative to a given template?
$id_parts[] = $this->_realpath($baseFilePath);
}
$id_parts[] = $name;
$id_parts[] = (string) $cache_id;
$id_parts[] = (string) $compile_id;
$id_parts[] = (string) $caching;
$_templateId = implode('#', $id_parts);
$_templateId = $resource_name . '#' . $cache_id . '#' . $compile_id . '#' . $caching;
// hash very long IDs to prevent problems with filename length
// do not hash shorter IDs so they remain recognizable
// do not hash shorter IDs, so they remain recognizable
if (strlen($_templateId) > 150) {
$_templateId = sha1($_templateId);
}
return $_templateId;
}
@@ -1089,9 +996,8 @@ class Smarty extends \Smarty\TemplateBase
*
* @return string
*/
public function _realpath($path, $realpath = null)
{
$nds = array('/' => '\\', '\\' => '/');
public function _realpath($path, $realpath = null) {
$nds = ['/' => '\\', '\\' => '/'];
preg_match(
'%^(?<root>(?:[[:alpha:]]:[\\\\/]|/|[\\\\]{2}[[:alpha:]]+|[[:print:]]{2,}:[/]{2}|[\\\\])?)(?<path>(.*))$%u',
$path,
@@ -1110,7 +1016,7 @@ class Smarty extends \Smarty\TemplateBase
$parts['root'] = str_replace($nds[DIRECTORY_SEPARATOR], DIRECTORY_SEPARATOR, $parts['root']);
do {
$path = preg_replace(
array('#[\\\\/]{2}#', '#[\\\\/][.][\\\\/]#', '#[\\\\/]([^\\\\/.]+)[\\\\/][.][.][\\\\/]#'),
['#[\\\\/]{2}#', '#[\\\\/][.][\\\\/]#', '#[\\\\/]([^\\\\/.]+)[\\\\/][.][.][\\\\/]#'],
DIRECTORY_SEPARATOR,
$path,
-1,
@@ -1123,24 +1029,21 @@ class Smarty extends \Smarty\TemplateBase
/**
* @param boolean $use_sub_dirs
*/
public function setUseSubDirs($use_sub_dirs)
{
public function setUseSubDirs($use_sub_dirs) {
$this->use_sub_dirs = $use_sub_dirs;
}
/**
* @param int $error_reporting
*/
public function setErrorReporting($error_reporting)
{
public function setErrorReporting($error_reporting) {
$this->error_reporting = $error_reporting;
}
/**
* @param boolean $escape_html
*/
public function setEscapeHtml($escape_html)
{
public function setEscapeHtml($escape_html) {
$this->escape_html = $escape_html;
}
@@ -1149,8 +1052,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return boolean
*/
public function getAutoLiteral()
{
public function getAutoLiteral() {
return $this->auto_literal;
}
@@ -1159,24 +1061,21 @@ class Smarty extends \Smarty\TemplateBase
*
* @param boolean $auto_literal
*/
public function setAutoLiteral($auto_literal = true)
{
public function setAutoLiteral($auto_literal = true) {
$this->auto_literal = $auto_literal;
}
/**
* @param boolean $force_compile
*/
public function setForceCompile($force_compile)
{
public function setForceCompile($force_compile) {
$this->force_compile = $force_compile;
}
/**
* @param boolean $merge_compiled_includes
*/
public function setMergeCompiledIncludes($merge_compiled_includes)
{
public function setMergeCompiledIncludes($merge_compiled_includes) {
$this->merge_compiled_includes = $merge_compiled_includes;
}
@@ -1185,8 +1084,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return string
*/
public function getLeftDelimiter()
{
public function getLeftDelimiter() {
return $this->left_delimiter;
}
@@ -1195,8 +1093,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @param string $left_delimiter
*/
public function setLeftDelimiter($left_delimiter)
{
public function setLeftDelimiter($left_delimiter) {
$this->left_delimiter = $left_delimiter;
}
@@ -1205,8 +1102,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return string $right_delimiter
*/
public function getRightDelimiter()
{
public function getRightDelimiter() {
return $this->right_delimiter;
}
@@ -1215,56 +1111,49 @@ class Smarty extends \Smarty\TemplateBase
*
* @param string
*/
public function setRightDelimiter($right_delimiter)
{
public function setRightDelimiter($right_delimiter) {
$this->right_delimiter = $right_delimiter;
}
/**
* @param boolean $debugging
*/
public function setDebugging($debugging)
{
public function setDebugging($debugging) {
$this->debugging = $debugging;
}
/**
* @param boolean $config_overwrite
*/
public function setConfigOverwrite($config_overwrite)
{
public function setConfigOverwrite($config_overwrite) {
$this->config_overwrite = $config_overwrite;
}
/**
* @param boolean $config_booleanize
*/
public function setConfigBooleanize($config_booleanize)
{
public function setConfigBooleanize($config_booleanize) {
$this->config_booleanize = $config_booleanize;
}
/**
* @param boolean $config_read_hidden
*/
public function setConfigReadHidden($config_read_hidden)
{
public function setConfigReadHidden($config_read_hidden) {
$this->config_read_hidden = $config_read_hidden;
}
/**
* @param boolean $compile_locking
*/
public function setCompileLocking($compile_locking)
{
public function setCompileLocking($compile_locking) {
$this->compile_locking = $compile_locking;
}
/**
* @param string $default_resource_type
*/
public function setDefaultResourceType($default_resource_type)
{
public function setDefaultResourceType($default_resource_type) {
$this->default_resource_type = $default_resource_type;
}
@@ -1273,18 +1162,16 @@ class Smarty extends \Smarty\TemplateBase
*
* @param null $errors
*/
public function testInstall(&$errors = null)
{
public function testInstall(&$errors = null) {
\Smarty\TestInstall::testInstall($this, $errors);
}
/**
* Get Smarty object
* // @TODO this is silly, remove?
*
* @return Smarty
*/
public function getSmarty()
{
public function getSmarty() {
return $this;
}
@@ -1294,8 +1181,7 @@ class Smarty extends \Smarty\TemplateBase
* @param string $dirName cache_dir or compile_dir
* @param string $dir filepath of folder
*/
private function _normalizeDir($dirName, $dir)
{
private function _normalizeDir($dirName, $dir) {
$this->{$dirName} = $this->_realpath(rtrim($dir ?? '', "/\\") . DIRECTORY_SEPARATOR, true);
}
@@ -1304,8 +1190,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @param bool $isConfig true for config_dir
*/
private function _normalizeTemplateConfig($isConfig)
{
private function _normalizeTemplateConfig($isConfig) {
if ($isConfig) {
$processed = &$this->_processedConfigDir;
$dir = &$this->config_dir;
@@ -1318,15 +1203,21 @@ class Smarty extends \Smarty\TemplateBase
}
foreach ($dir as $k => $v) {
if (!isset($processed[$k])) {
$dir[ $k ] = $v = $this->_realpath(rtrim($v ?? '', "/\\") . DIRECTORY_SEPARATOR, true);
$dir[$k] = $this->_realpath(rtrim($v ?? '', "/\\") . DIRECTORY_SEPARATOR, true);
$processed[$k] = true;
}
}
$isConfig ? $this->_configDirNormalized = true : $this->_templateDirNormalized = true;
$isConfig ? $this->_joined_config_dir = join('#', $this->config_dir) :
if ($isConfig) {
$this->_configDirNormalized = true;
$this->_joined_config_dir = join('#', $this->config_dir);
} else {
$this->_templateDirNormalized = true;
$this->_joined_template_dir = join('#', $this->template_dir);
}
}
/**
* Mutes errors for "undefined index", "undefined array key" and "trying to read property of null".
*
@@ -1338,6 +1229,7 @@ class Smarty extends \Smarty\TemplateBase
/**
* Indicates if Smarty will mute errors for "undefined index", "undefined array key" and "trying to read property of null".
*
* @return bool
*/
public function isMutingUndefinedOrNullWarnings(): bool {
@@ -1371,16 +1263,15 @@ class Smarty extends \Smarty\TemplateBase
/**
* Empty cache folder
*
* @api Smarty::clearAllCache()
* @link https://www.smarty.net/docs/en/api.clear.all.cache.tpl
*
* @param integer $exp_time expiration time
* @param string $type resource type
*
* @return int number of cache files deleted
* @link https://www.smarty.net/docs/en/api.clear.all.cache.tpl
*
* @api Smarty::clearAllCache()
*/
public function clearAllCache($exp_time = null)
{
public function clearAllCache($exp_time = null) {
return $this->getCacheResource()->clearAll($this, $exp_time);
}
@@ -1397,8 +1288,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @api Smarty::clearCompiledTemplate()
*/
public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
{
public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null) {
$_compile_dir = $this->getCompileDir();
if ($_compile_dir === '/') { //We should never want to delete this!
return 0;
@@ -1409,7 +1299,7 @@ class Smarty extends \Smarty\TemplateBase
$_save_stat = $this->caching;
$this->caching = \Smarty\Smarty::CACHING_OFF;
/* @var Template $tpl */
$tpl = $this->createTemplate($resource_name);
$tpl = $this->doCreateTemplate($resource_name);
$this->caching = $_save_stat;
if (!$tpl->getSource()->handler->recompiled && $tpl->getSource()->exists) {
$_resource_part_1 = basename(str_replace('^', DIRECTORY_SEPARATOR, $tpl->getCompiled()->filepath));
@@ -1495,14 +1385,14 @@ class Smarty extends \Smarty\TemplateBase
/**
* Compile all template files
*
* @api Smarty::compileAllTemplates()
*
* @param string $extension file extension
* @param bool $force_compile force all to recompile
* @param int $time_limit
* @param int $max_errors
*
* @return integer number of template files recompiled
* @api Smarty::compileAllTemplates()
*
*/
public function compileAllTemplates(
$extension = '.tpl',
@@ -1516,14 +1406,14 @@ class Smarty extends \Smarty\TemplateBase
/**
* Compile all config files
*
* @api Smarty::compileAllConfig()
*
* @param string $extension file extension
* @param bool $force_compile force all to recompile
* @param int $time_limit
* @param int $max_errors
*
* @return int number of template files recompiled
* @api Smarty::compileAllConfig()
*
*/
public function compileAllConfig(
$extension = '.conf',
@@ -1585,7 +1475,7 @@ class Smarty extends \Smarty\TemplateBase
//
$_smarty->force_compile = $force_compile;
try {
$_tpl = $this->createTemplate($_file);
$_tpl = $this->doCreateTemplate($_file);
$_tpl->caching = self::CACHING_OFF;
$_tpl->setSource(
$isConfig ? \Smarty\Template\Config::load($_tpl) : \Smarty\Template\Source::load($_tpl)
@@ -1625,8 +1515,7 @@ class Smarty extends \Smarty\TemplateBase
* @throws \Exception
* @throws \Smarty\Exception
*/
public function cacheModifiedCheck(Template\Cached $cached, Template $_template, $content)
{
public function cacheModifiedCheck(Template\Cached $cached, Template $_template, $content) {
$_isCached = $_template->isCached() && !$_template->getCompiled()->getNocacheCode();
$_last_modified_date =
@substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
@@ -1716,8 +1605,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return string the filtered source
*/
public function runPreFilters($source, Template $template)
{
public function runPreFilters($source, Template $template) {
foreach ($this->getExtensions() as $extension) {
/** @var \Smarty\Filter\FilterInterface $filter */
@@ -1738,8 +1626,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return string the filtered code
*/
public function runPostFilters($code, Template $template)
{
public function runPostFilters($code, Template $template) {
foreach ($this->getExtensions() as $extension) {
/** @var \Smarty\Filter\FilterInterface $filter */
@@ -1760,8 +1647,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return string the filtered (modified) output
*/
public function runOutputFilters($content, Template $template)
{
public function runOutputFilters($content, Template $template) {
foreach ($this->getExtensions() as $extension) {
/** @var \Smarty\Filter\FilterInterface $filter */
@@ -1783,8 +1669,7 @@ class Smarty extends \Smarty\TemplateBase
* @return boolean true
* @throws Exception
*/
public function writeFile($_filepath, $_contents)
{
public function writeFile($_filepath, $_contents) {
$_error_reporting = error_reporting();
error_reporting($_error_reporting & ~E_NOTICE & ~E_WARNING);
$_dirpath = dirname($_filepath);
@@ -1806,7 +1691,7 @@ class Smarty extends \Smarty\TemplateBase
}
}
// write to tmp file, then move to overt file lock race condition
$_tmp_file = $_dirpath . DIRECTORY_SEPARATOR . str_replace(array('.', ','), '_', uniqid('wrt', true));
$_tmp_file = $_dirpath . DIRECTORY_SEPARATOR . str_replace(['.', ','], '_', uniqid('wrt', true));
if (!file_put_contents($_tmp_file, $_contents)) {
error_reporting($_error_reporting);
throw new Exception("unable to write file {$_tmp_file}");
@@ -1847,11 +1732,11 @@ class Smarty extends \Smarty\TemplateBase
return true;
}
private $runtimes = [];
/**
* Loads and returns a runtime extension or null if not found
*
* @param string $type
*
* @return object|null
@@ -1919,8 +1804,6 @@ class Smarty extends \Smarty\TemplateBase
*/
public function loadFilter($type, $name) {
if ($type == \Smarty\Smarty::FILTER_VARIABLE) {
foreach ($this->getExtensions() as $extension) {
if ($extension->getModifierCallback($name)) {
@@ -1993,6 +1876,7 @@ class Smarty extends \Smarty\TemplateBase
$this->_caching_type = $type;
$this->activateBCCacheResource();
}
/**
* @return string
* @deprecated since 5.0
@@ -2108,8 +1992,7 @@ class Smarty extends \Smarty\TemplateBase
*
* @return string|null internal filter name or null if callable cannot be serialized
*/
private function _getFilterName($callable)
{
private function _getFilterName($callable) {
if (is_array($callable)) {
$_class_name = is_object($callable[0]) ? get_class($callable[0]) : $callable[0];
return $_class_name . '_' . $callable[1];
@@ -2158,7 +2041,6 @@ class Smarty extends \Smarty\TemplateBase
return $this;
}
/**
* Add default modifiers
*
@@ -2178,7 +2060,6 @@ class Smarty extends \Smarty\TemplateBase
return $this;
}
/**
* Get default modifiers
*
@@ -2205,10 +2086,6 @@ class Smarty extends \Smarty\TemplateBase
return $this;
}
public function setAllowAmbiguousResources(bool $allow) {
$this->allow_ambiguous_resources = $allow;
}
/**
* @return Cacheresource\Base
*/
@@ -2252,6 +2129,62 @@ class Smarty extends \Smarty\TemplateBase
return $this->returnOrCreateTemplate($template, $cache_id, $compile_id)->display();
}
/**
* @param $resource_name
* @param $cache_id
* @param $compile_id
* @param $parent
* @param $caching
* @param $cache_lifetime
* @param bool $isConfig
* @param array $data
*
* @return Template
* @throws Exception
*/
public function doCreateTemplate(
$resource_name,
$cache_id = null,
$compile_id = null,
$parent = null,
$caching = null,
$cache_lifetime = null,
bool $isConfig = false,
array $data = []): Template {
if (!$this->_templateDirNormalized) {
$this->_normalizeTemplateConfig(false);
}
$_templateId = $this->generateUniqueTemplateId($resource_name, $cache_id, $compile_id, $caching);
if (!isset($this->templates[$_templateId])) {
$newTemplate = new Template($resource_name, $this, $parent ?: $this, $cache_id, $compile_id, $caching, $isConfig);
$newTemplate->templateId = $_templateId; // @TODO this could go in constructor ^?
$this->templates[$_templateId] = $newTemplate;
}
$tpl = clone $this->templates[$_templateId];
$tpl->setParent($parent ?: $this);
if ($cache_lifetime) {
$tpl->setCacheLifetime($cache_lifetime);
}
// fill data if present
foreach ($data as $_key => $_val) {
$tpl->assign($_key, $_val);
}
$tpl->tplFunctions = array_merge($parent->tplFunctions ?? [], $tpl->tplFunctions ?? []);
if (!$this->debugging && $this->debugging_ctrl === 'URL') {
$tpl->getSmarty()->getDebug()->debugUrl($tpl->getSmarty());
}
return $tpl;
}
/**
* test if cache is valid
*

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,30 +248,35 @@ 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);
}
}
if ($tpl->caching === \Smarty\Template::CACHING_NOCACHE_CODE) {
if ($tpl->getCompiled()->getNocacheCode()) {
$this->getCached()->hashes[$tpl->getCompiled()->nocache_hash] = true;
@@ -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
);
if ($this->isCachingEnabled()) {
$cacheResource->populate($this->cached, $this);
if (!$this->isCachingEnabled()) {
} 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.
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;
}
if (isset(self::$_incompatible_resources[$type])) {
throw new Exception("Unable to use resource '{$type}' for " . __METHOD__);
}
// create new source object
$source = new Source($smarty, $template_resource, $type, $name);
$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}'"
);
}
$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;
$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,7 +77,9 @@ 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()
@@ -109,7 +87,8 @@ class FileResourceIndexedTest extends PHPUnit_Smarty
$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);
$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;