mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-05 10:54:27 +02:00
rework source resource handling
- move class Smarty_Template_Source into its own file - impelement all source processing into the classes it better belongs to
This commit is contained in:
@@ -10,12 +10,10 @@
|
|||||||
*
|
*
|
||||||
* @package Smarty
|
* @package Smarty
|
||||||
* @author Uwe Tews
|
* @author Uwe Tews
|
||||||
*
|
|
||||||
* Usage:
|
* Usage:
|
||||||
* include '...path/Autoloader.php';
|
* include '...path/Autoloader.php';
|
||||||
* Smarty_Autoloader::register();
|
* Smarty_Autoloader::register();
|
||||||
* $smarty = new Smarty();
|
* $smarty = new Smarty();
|
||||||
*
|
|
||||||
* Note: This autoloader is not needed if you use Composer.
|
* Note: This autoloader is not needed if you use Composer.
|
||||||
* Composer will automatically add the classes of the Smarty package to it common autoloader.
|
* Composer will automatically add the classes of the Smarty package to it common autoloader.
|
||||||
*/
|
*/
|
||||||
@@ -59,6 +57,8 @@ class Smarty_Autoloader
|
|||||||
'smarty_resource_custom' => true,
|
'smarty_resource_custom' => true,
|
||||||
'smarty_resource_uncompiled' => true,
|
'smarty_resource_uncompiled' => true,
|
||||||
'smarty_resource_recompiled' => true,
|
'smarty_resource_recompiled' => true,
|
||||||
|
'smarty_template_source' => true,
|
||||||
|
'smarty_template_compiled' => true,
|
||||||
'smartyexception' => true,
|
'smartyexception' => true,
|
||||||
'smartycompilerexception' => true,
|
'smartycompilerexception' => true,
|
||||||
);
|
);
|
||||||
|
@@ -73,11 +73,11 @@ class Smarty_Internal_Resource_Eval extends Smarty_Resource_Recompiled
|
|||||||
*
|
*
|
||||||
* @param Smarty $smarty Smarty instance
|
* @param Smarty $smarty Smarty instance
|
||||||
* @param string $resource_name resource_name to make unique
|
* @param string $resource_name resource_name to make unique
|
||||||
* @param boolean $is_config flag for config resource
|
* @param boolean $isConfig flag for config resource
|
||||||
*
|
*
|
||||||
* @return string unique resource name
|
* @return string unique resource name
|
||||||
*/
|
*/
|
||||||
protected function buildUniqueResourceName(Smarty $smarty, $resource_name, $is_config = false)
|
public function buildUniqueResourceName(Smarty $smarty, $resource_name, $isConfig = false)
|
||||||
{
|
{
|
||||||
return get_class($this) . '#' . $this->decode($resource_name);
|
return get_class($this) . '#' . $this->decode($resource_name);
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ class Smarty_Internal_Resource_Eval extends Smarty_Resource_Recompiled
|
|||||||
*
|
*
|
||||||
* @return string resource's basename
|
* @return string resource's basename
|
||||||
*/
|
*/
|
||||||
protected function getBasename(Smarty_Template_Source $source)
|
public function getBasename(Smarty_Template_Source $source)
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@@ -34,7 +34,7 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource
|
|||||||
*/
|
*/
|
||||||
public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null)
|
public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null)
|
||||||
{
|
{
|
||||||
$uid = '';
|
$uid = sha1(getcwd());
|
||||||
$sources = array();
|
$sources = array();
|
||||||
$components = explode('|', $source->name);
|
$components = explode('|', $source->name);
|
||||||
$exists = true;
|
$exists = true;
|
||||||
|
@@ -17,6 +17,145 @@
|
|||||||
*/
|
*/
|
||||||
class Smarty_Internal_Resource_File extends Smarty_Resource
|
class Smarty_Internal_Resource_File extends Smarty_Resource
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* build template filepath by traversing the template_dir array
|
||||||
|
*
|
||||||
|
* @param Smarty_Template_Source $source source object
|
||||||
|
* @param Smarty_Internal_Template $_template template object
|
||||||
|
*
|
||||||
|
* @return string fully qualified filepath
|
||||||
|
* @throws SmartyException
|
||||||
|
*/
|
||||||
|
protected function buildFilepath(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null)
|
||||||
|
{
|
||||||
|
$file = str_replace(array('\\', '/./'), '/', $source->name);
|
||||||
|
if ($source->isConfig) {
|
||||||
|
$_directories = $source->smarty->getConfigDir();
|
||||||
|
} else {
|
||||||
|
$_directories = $source->smarty->getTemplateDir();
|
||||||
|
}
|
||||||
|
preg_match('#^((?P<absolute>[\/]|[a-zA-Z]:[\/])|(\[(?P<index>[^\]]+)\])|((?P<rel1>\.[\/])?(?P<rel2>(\.\.[\/])*))|(?P<skip>[\/]))?(?P<file>.+)$#', $file, $fileMatch);
|
||||||
|
// go relative to a given template?
|
||||||
|
if ($_template && $_template->parent instanceof Smarty_Internal_Template && (!empty($fileMatch['rel1']) || !empty($fileMatch['rel2']))) {
|
||||||
|
if ($_template->parent->source->type != 'file' && $_template->parent->source->type != 'extends' && !$_template->parent->allow_relative_path) {
|
||||||
|
throw new SmartyException("Template '{$file}' cannot be relative to template of resource type '{$_template->parent->source->type}'");
|
||||||
|
}
|
||||||
|
$path = dirname($_template->parent->source->filepath);
|
||||||
|
if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $path)) {
|
||||||
|
// the path gained from the parent template is relative to the current working directory
|
||||||
|
// as expansions (like include_path) have already been done
|
||||||
|
$path = getcwd() . '/' . $path;
|
||||||
|
}
|
||||||
|
// normalize path
|
||||||
|
$path = str_replace(array('\\', './'), array('/', ''), $path);
|
||||||
|
// simple relative
|
||||||
|
if (!empty($fileMatch['rel1'])) {
|
||||||
|
$file = $path . '/' . $fileMatch['file'];
|
||||||
|
} else {
|
||||||
|
for ($i = 1; $i <= substr_count($fileMatch['rel2'], '../'); $i ++) {
|
||||||
|
$path = substr($path, 0, strrpos($path, '/'));
|
||||||
|
}
|
||||||
|
$file = $path . '/' . $fileMatch['file'];
|
||||||
|
}
|
||||||
|
// files relative to a template only get one shot
|
||||||
|
return $this->fileExists($source, $file) ? $file : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$_filepath = null;
|
||||||
|
// template_dir index?
|
||||||
|
if (!empty($fileMatch['index'])) {
|
||||||
|
$index = $fileMatch['index'];
|
||||||
|
$_directory = null;
|
||||||
|
// try string indexes
|
||||||
|
if (isset($_directories[$index])) {
|
||||||
|
$_directory = $_directories[$index];
|
||||||
|
} elseif (is_numeric($index)) {
|
||||||
|
// try numeric index
|
||||||
|
$index = (int) $index;
|
||||||
|
if (isset($_directories[$index])) {
|
||||||
|
$_directory = $_directories[$index];
|
||||||
|
} else {
|
||||||
|
// try at location index
|
||||||
|
$keys = array_keys($_directories);
|
||||||
|
$_directory = $_directories[$keys[$index]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($_directory) {
|
||||||
|
$_filepath = $_directory . $fileMatch['file'];
|
||||||
|
if ($this->fileExists($source, $_filepath)) {
|
||||||
|
return $_filepath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// relative file name?
|
||||||
|
if (empty($fileMatch['absolute'])) {
|
||||||
|
foreach ($_directories as $_directory) {
|
||||||
|
if (!empty($fileMatch['rel2'])) {
|
||||||
|
for ($i = 1; $i <= substr_count($fileMatch['rel2'], '../') + 1; $i ++) {
|
||||||
|
$_directory = substr($_directory, 0, strrpos($_directory, '/'));
|
||||||
|
}
|
||||||
|
$_filepath = $_directory . '/' . $fileMatch['file'];
|
||||||
|
} else {
|
||||||
|
$_filepath = $_directory . $fileMatch['file'];
|
||||||
|
}
|
||||||
|
if ($this->fileExists($source, $_filepath)) {
|
||||||
|
return $_filepath;
|
||||||
|
}
|
||||||
|
if ($source->smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_directory)) {
|
||||||
|
// try PHP include_path
|
||||||
|
if (function_exists('stream_resolve_include_path')) {
|
||||||
|
$_filepath = stream_resolve_include_path($_filepath);
|
||||||
|
} else {
|
||||||
|
$_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_filepath !== false) {
|
||||||
|
if ($this->fileExists($source, $_filepath)) {
|
||||||
|
return $_filepath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// try absolute filepath
|
||||||
|
if ($this->fileExists($source, $file)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Could be relative to cwd
|
||||||
|
if (empty($fileMatch['rel1'])) {
|
||||||
|
$file = getcwd() . '/' . $fileMatch['file'];
|
||||||
|
} else {
|
||||||
|
$path = getcwd();
|
||||||
|
for ($i = 1; $i <= substr_count($fileMatch['rel2'], '../'); $i ++) {
|
||||||
|
$path = substr($path, 0, strrpos($path, '/'));
|
||||||
|
}
|
||||||
|
$file = $path . '/' . $fileMatch['file'];
|
||||||
|
}
|
||||||
|
if ($this->fileExists($source, $file)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
// give up
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test is file exists and save timestamp
|
||||||
|
*
|
||||||
|
* @param Smarty_Template_Source $source source object
|
||||||
|
* @param string $file file name
|
||||||
|
*
|
||||||
|
* @return bool true if file exists
|
||||||
|
*/
|
||||||
|
protected function fileExists(Smarty_Template_Source $source, $file)
|
||||||
|
{
|
||||||
|
$source->timestamp = is_file($file) ? @filemtime($file) : false;
|
||||||
|
return $source->exists = !!$source->timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* populate Source Object with meta data from Resource
|
* populate Source Object with meta data from Resource
|
||||||
*
|
*
|
||||||
@@ -32,7 +171,7 @@ class Smarty_Internal_Resource_File extends Smarty_Resource
|
|||||||
$source->smarty->security_policy->isTrustedResourceDir($source->filepath);
|
$source->smarty->security_policy->isTrustedResourceDir($source->filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
$source->uid = sha1(realpath($source->filepath));
|
$source->uid = sha1(getcwd() . $source->filepath);
|
||||||
if ($source->smarty->compile_check && !isset($source->timestamp)) {
|
if ($source->smarty->compile_check && !isset($source->timestamp)) {
|
||||||
$source->timestamp = @filemtime($source->filepath);
|
$source->timestamp = @filemtime($source->filepath);
|
||||||
$source->exists = !!$source->timestamp;
|
$source->exists = !!$source->timestamp;
|
||||||
|
@@ -9,8 +9,14 @@
|
|||||||
* @author Uwe Tews
|
* @author Uwe Tews
|
||||||
* @author Rodney Rehm
|
* @author Rodney Rehm
|
||||||
*/
|
*/
|
||||||
class Smarty_Internal_Resource_Php extends Smarty_Resource_Uncompiled
|
class Smarty_Internal_Resource_PHP extends Smarty_Internal_Resource_File
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Flag that it's an uncompiled resource
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $uncompiled = true;
|
||||||
/**
|
/**
|
||||||
* container for short_open_tag directive's value before executing PHP templates
|
* container for short_open_tag directive's value before executing PHP templates
|
||||||
*
|
*
|
||||||
@@ -116,4 +122,17 @@ class Smarty_Internal_Resource_Php extends Smarty_Resource_Uncompiled
|
|||||||
include($source->filepath);
|
include($source->filepath);
|
||||||
ini_set('short_open_tag', $this->short_open_tag);
|
ini_set('short_open_tag', $this->short_open_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* populate compiled object with compiled filepath
|
||||||
|
*
|
||||||
|
* @param Smarty_Template_Compiled $compiled compiled object
|
||||||
|
* @param Smarty_Internal_Template $_template template object (is ignored)
|
||||||
|
*/
|
||||||
|
public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template)
|
||||||
|
{
|
||||||
|
$compiled->filepath = false;
|
||||||
|
$compiled->timestamp = false;
|
||||||
|
$compiled->exists = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -91,7 +91,7 @@ class Smarty_Internal_Resource_Registered extends Smarty_Resource
|
|||||||
*
|
*
|
||||||
* @return string resource's basename
|
* @return string resource's basename
|
||||||
*/
|
*/
|
||||||
protected function getBasename(Smarty_Template_Source $source)
|
public function getBasename(Smarty_Template_Source $source)
|
||||||
{
|
{
|
||||||
return basename($source->name);
|
return basename($source->name);
|
||||||
}
|
}
|
||||||
|
@@ -70,11 +70,11 @@ class Smarty_Internal_Resource_Stream extends Smarty_Resource_Recompiled
|
|||||||
*
|
*
|
||||||
* @param Smarty $smarty Smarty instance
|
* @param Smarty $smarty Smarty instance
|
||||||
* @param string $resource_name resource_name to make unique
|
* @param string $resource_name resource_name to make unique
|
||||||
* @param boolean $is_config flag for config resource
|
* @param boolean $isConfig flag for config resource
|
||||||
*
|
*
|
||||||
* @return string unique resource name
|
* @return string unique resource name
|
||||||
*/
|
*/
|
||||||
protected function buildUniqueResourceName(Smarty $smarty, $resource_name, $is_config = false)
|
public function buildUniqueResourceName(Smarty $smarty, $resource_name, $isConfig = false)
|
||||||
{
|
{
|
||||||
return get_class($this) . '#' . $resource_name;
|
return get_class($this) . '#' . $resource_name;
|
||||||
}
|
}
|
||||||
|
@@ -73,11 +73,11 @@ class Smarty_Internal_Resource_String extends Smarty_Resource
|
|||||||
*
|
*
|
||||||
* @param Smarty $smarty Smarty instance
|
* @param Smarty $smarty Smarty instance
|
||||||
* @param string $resource_name resource_name to make unique
|
* @param string $resource_name resource_name to make unique
|
||||||
* @param boolean $is_config flag for config resource
|
* @param boolean $isConfig flag for config resource
|
||||||
*
|
*
|
||||||
* @return string unique resource name
|
* @return string unique resource name
|
||||||
*/
|
*/
|
||||||
protected function buildUniqueResourceName(Smarty $smarty, $resource_name, $is_config = false)
|
public function buildUniqueResourceName(Smarty $smarty, $resource_name, $isConfig = false)
|
||||||
{
|
{
|
||||||
return get_class($this) . '#' . $this->decode($resource_name);
|
return get_class($this) . '#' . $this->decode($resource_name);
|
||||||
}
|
}
|
||||||
@@ -90,7 +90,7 @@ class Smarty_Internal_Resource_String extends Smarty_Resource
|
|||||||
*
|
*
|
||||||
* @return string resource's basename
|
* @return string resource's basename
|
||||||
*/
|
*/
|
||||||
protected function getBasename(Smarty_Template_Source $source)
|
public function getBasename(Smarty_Template_Source $source)
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,25 @@
|
|||||||
*/
|
*/
|
||||||
abstract class Smarty_Resource
|
abstract class Smarty_Resource
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Source is bypassing compiler
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
public $uncompiled = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source must be recompiled on every occasion
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
public $recompiled = false;
|
||||||
|
/**
|
||||||
|
* resource handler object
|
||||||
|
*
|
||||||
|
* @var Smarty_Resource
|
||||||
|
*/
|
||||||
|
public $handler = null;
|
||||||
/**
|
/**
|
||||||
* cache for Smarty_Template_Source instances
|
* cache for Smarty_Template_Source instances
|
||||||
*
|
*
|
||||||
@@ -28,12 +47,6 @@ abstract class Smarty_Resource
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public static $compileds = array();
|
public static $compileds = array();
|
||||||
/**
|
|
||||||
* cache for Smarty_Resource instances
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public static $resources = array();
|
|
||||||
/**
|
/**
|
||||||
* resource types provided by the core
|
* resource types provided by the core
|
||||||
*
|
*
|
||||||
@@ -103,270 +116,19 @@ abstract class Smarty_Resource
|
|||||||
*
|
*
|
||||||
* @param Smarty $smarty Smarty instance
|
* @param Smarty $smarty Smarty instance
|
||||||
* @param string $resource_name resource_name to make unique
|
* @param string $resource_name resource_name to make unique
|
||||||
* @param boolean $is_config flag for config resource
|
* @param boolean $isConfig flag for config resource
|
||||||
*
|
*
|
||||||
* @return string unique resource name
|
* @return string unique resource name
|
||||||
*/
|
*/
|
||||||
protected function buildUniqueResourceName(Smarty $smarty, $resource_name, $is_config = false)
|
public function buildUniqueResourceName(Smarty $smarty, $resource_name, $isConfig = false)
|
||||||
{
|
{
|
||||||
if ($is_config) {
|
if ($isConfig) {
|
||||||
return get_class($this) . '#' . $smarty->joined_config_dir . '#' . $resource_name;
|
return get_class($this) . '#' . $smarty->joined_config_dir . '#' . $resource_name;
|
||||||
} else {
|
} else {
|
||||||
return get_class($this) . '#' . $smarty->joined_template_dir . '#' . $resource_name;
|
return get_class($this) . '#' . $smarty->joined_template_dir . '#' . $resource_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* populate Compiled Object with compiled filepath
|
|
||||||
*
|
|
||||||
* @param Smarty_Template_Compiled $compiled compiled object
|
|
||||||
* @param Smarty_Internal_Template $_template template object
|
|
||||||
*/
|
|
||||||
public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template)
|
|
||||||
{
|
|
||||||
$_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null;
|
|
||||||
$_filepath = $compiled->source->uid;
|
|
||||||
// if use_sub_dirs, break file into directories
|
|
||||||
if ($_template->smarty->use_sub_dirs) {
|
|
||||||
$_filepath = substr($_filepath, 0, 2) . DS
|
|
||||||
. substr($_filepath, 2, 2) . DS
|
|
||||||
. substr($_filepath, 4, 2) . DS
|
|
||||||
. $_filepath;
|
|
||||||
}
|
|
||||||
$_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^';
|
|
||||||
if (isset($_compile_id)) {
|
|
||||||
$_filepath = $_compile_id . $_compile_dir_sep . $_filepath;
|
|
||||||
}
|
|
||||||
// caching token
|
|
||||||
if ($_template->caching) {
|
|
||||||
$_cache = '.cache';
|
|
||||||
} else {
|
|
||||||
$_cache = '';
|
|
||||||
}
|
|
||||||
$_compile_dir = $_template->smarty->getCompileDir();
|
|
||||||
// set basename if not specified
|
|
||||||
$_basename = $this->getBasename($compiled->source);
|
|
||||||
if ($_basename === null) {
|
|
||||||
$_basename = basename(preg_replace('![^\w\/]+!', '_', $compiled->source->name));
|
|
||||||
}
|
|
||||||
// separate (optional) basename by dot
|
|
||||||
if ($_basename) {
|
|
||||||
$_basename = '.' . $_basename;
|
|
||||||
}
|
|
||||||
|
|
||||||
$compiled->filepath = $_compile_dir . $_filepath . '.' . $compiled->source->type . $_basename . $_cache . '.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normalize Paths "foo/../bar" to "bar"
|
|
||||||
*
|
|
||||||
* @param string $_path path to normalize
|
|
||||||
* @param boolean $ds respect windows directory separator
|
|
||||||
*
|
|
||||||
* @return string normalized path
|
|
||||||
*/
|
|
||||||
protected function normalizePath($_path, $ds = true)
|
|
||||||
{
|
|
||||||
if ($ds) {
|
|
||||||
// don't we all just love windows?
|
|
||||||
$_path = str_replace('\\', '/', $_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
$offset = 0;
|
|
||||||
|
|
||||||
// resolve simples
|
|
||||||
$_path = preg_replace('#/\./(\./)*#', '/', $_path);
|
|
||||||
// resolve parents
|
|
||||||
while (true) {
|
|
||||||
$_parent = strpos($_path, '/../', $offset);
|
|
||||||
if (!$_parent) {
|
|
||||||
break;
|
|
||||||
} elseif ($_path[$_parent - 1] === '.') {
|
|
||||||
$offset = $_parent + 3;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$_pos = strrpos($_path, '/', $_parent - strlen($_path) - 1);
|
|
||||||
if ($_pos === false) {
|
|
||||||
// don't we all just love windows?
|
|
||||||
$_pos = $_parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
$_path = substr_replace($_path, '', $_pos, $_parent + 3 - $_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($ds && DS != '/') {
|
|
||||||
// don't we all just love windows?
|
|
||||||
$_path = str_replace('/', '\\', $_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* build template filepath by traversing the template_dir array
|
|
||||||
*
|
|
||||||
* @param Smarty_Template_Source $source source object
|
|
||||||
* @param Smarty_Internal_Template $_template template object
|
|
||||||
*
|
|
||||||
* @return string fully qualified filepath
|
|
||||||
* @throws SmartyException if default template handler is registered but not callable
|
|
||||||
*/
|
|
||||||
protected function buildFilepath(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null)
|
|
||||||
{
|
|
||||||
$file = $source->name;
|
|
||||||
if ($source instanceof Smarty_Config_Source) {
|
|
||||||
$_directories = $source->smarty->getConfigDir();
|
|
||||||
$_default_handler = $source->smarty->default_config_handler_func;
|
|
||||||
} else {
|
|
||||||
$_directories = $source->smarty->getTemplateDir();
|
|
||||||
$_default_handler = $source->smarty->default_template_handler_func;
|
|
||||||
}
|
|
||||||
|
|
||||||
// go relative to a given template?
|
|
||||||
$_file_is_dotted = $file[0] == '.' && ($file[1] == '.' || $file[1] == '/' || $file[1] == "\\");
|
|
||||||
if ($_template && $_template->parent instanceof Smarty_Internal_Template && $_file_is_dotted) {
|
|
||||||
if ($_template->parent->source->type != 'file' && $_template->parent->source->type != 'extends' && !$_template->parent->allow_relative_path) {
|
|
||||||
throw new SmartyException("Template '{$file}' cannot be relative to template of resource type '{$_template->parent->source->type}'");
|
|
||||||
}
|
|
||||||
$file = dirname($_template->parent->source->filepath) . DS . $file;
|
|
||||||
$_file_exact_match = true;
|
|
||||||
if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) {
|
|
||||||
// the path gained from the parent template is relative to the current working directory
|
|
||||||
// as expansions (like include_path) have already been done
|
|
||||||
$file = getcwd() . DS . $file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// resolve relative path
|
|
||||||
if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) {
|
|
||||||
// don't we all just love windows?
|
|
||||||
$_path = DS . trim($file, '/');
|
|
||||||
$_was_relative = true;
|
|
||||||
} else {
|
|
||||||
// don't we all just love windows?
|
|
||||||
$_path = str_replace('\\', '/', $file);
|
|
||||||
}
|
|
||||||
$_path = $this->normalizePath($_path, false);
|
|
||||||
if (DS != '/') {
|
|
||||||
// don't we all just love windows?
|
|
||||||
$_path = str_replace('/', '\\', $_path);
|
|
||||||
}
|
|
||||||
// revert to relative
|
|
||||||
if (isset($_was_relative)) {
|
|
||||||
$_path = substr($_path, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is only required for directories
|
|
||||||
$file = rtrim($_path, '/\\');
|
|
||||||
|
|
||||||
// files relative to a template only get one shot
|
|
||||||
if (isset($_file_exact_match)) {
|
|
||||||
return $this->fileExists($source, $file) ? $file : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// template_dir index?
|
|
||||||
if (preg_match('#^\[(?P<key>[^\]]+)\](?P<file>.+)$#', $file, $match)) {
|
|
||||||
$_directory = null;
|
|
||||||
// try string indexes
|
|
||||||
if (isset($_directories[$match['key']])) {
|
|
||||||
$_directory = $_directories[$match['key']];
|
|
||||||
} elseif (is_numeric($match['key'])) {
|
|
||||||
// try numeric index
|
|
||||||
$match['key'] = (int) $match['key'];
|
|
||||||
if (isset($_directories[$match['key']])) {
|
|
||||||
$_directory = $_directories[$match['key']];
|
|
||||||
} else {
|
|
||||||
// try at location index
|
|
||||||
$keys = array_keys($_directories);
|
|
||||||
$_directory = $_directories[$keys[$match['key']]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($_directory) {
|
|
||||||
$_file = substr($file, strpos($file, ']') + 1);
|
|
||||||
$_filepath = $_directory . $_file;
|
|
||||||
if ($this->fileExists($source, $_filepath)) {
|
|
||||||
return $_filepath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$_stream_resolve_include_path = function_exists('stream_resolve_include_path');
|
|
||||||
|
|
||||||
// relative file name?
|
|
||||||
if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) {
|
|
||||||
foreach ($_directories as $_directory) {
|
|
||||||
$_filepath = $_directory . $file;
|
|
||||||
if ($this->fileExists($source, $_filepath)) {
|
|
||||||
return $this->normalizePath($_filepath);
|
|
||||||
}
|
|
||||||
if ($source->smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_directory)) {
|
|
||||||
// try PHP include_path
|
|
||||||
if ($_stream_resolve_include_path) {
|
|
||||||
$_filepath = stream_resolve_include_path($_filepath);
|
|
||||||
} else {
|
|
||||||
$_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($_filepath !== false) {
|
|
||||||
if ($this->fileExists($source, $_filepath)) {
|
|
||||||
return $this->normalizePath($_filepath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// try absolute filepath
|
|
||||||
if ($this->fileExists($source, $file)) {
|
|
||||||
return $file;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no tpl file found
|
|
||||||
if ($_default_handler) {
|
|
||||||
if (!is_callable($_default_handler)) {
|
|
||||||
if ($source instanceof Smarty_Config_Source) {
|
|
||||||
throw new SmartyException("Default config handler not callable");
|
|
||||||
} else {
|
|
||||||
throw new SmartyException("Default template handler not callable");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$_return = call_user_func_array($_default_handler,
|
|
||||||
array($source->type, $source->name, &$_content, &$_timestamp, $source->smarty));
|
|
||||||
if (is_string($_return)) {
|
|
||||||
$source->timestamp = @filemtime($_return);
|
|
||||||
$source->exists = !!$source->timestamp;
|
|
||||||
|
|
||||||
return $_return;
|
|
||||||
} elseif ($_return === true) {
|
|
||||||
$source->content = $_content;
|
|
||||||
$source->timestamp = $_timestamp;
|
|
||||||
$source->exists = true;
|
|
||||||
|
|
||||||
return $_filepath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// give up
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test is file exists and save timestamp
|
|
||||||
*
|
|
||||||
* @param Smarty_Template_Source $source source object
|
|
||||||
* @param string $file file name
|
|
||||||
*
|
|
||||||
* @return bool true if file exists
|
|
||||||
*/
|
|
||||||
protected function fileExists(Smarty_Template_Source $source, $file)
|
|
||||||
{
|
|
||||||
$source->timestamp = is_file($file) ? @filemtime($file) : false;
|
|
||||||
|
|
||||||
return $source->exists = !!$source->timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine basename for compiled filename
|
* Determine basename for compiled filename
|
||||||
*
|
*
|
||||||
@@ -374,7 +136,7 @@ abstract class Smarty_Resource
|
|||||||
*
|
*
|
||||||
* @return string resource's basename
|
* @return string resource's basename
|
||||||
*/
|
*/
|
||||||
protected function getBasename(Smarty_Template_Source $source)
|
public function getBasename(Smarty_Template_Source $source)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -399,15 +161,8 @@ abstract class Smarty_Resource
|
|||||||
if (isset($smarty->registered_resources[$type])) {
|
if (isset($smarty->registered_resources[$type])) {
|
||||||
if ($smarty->registered_resources[$type] instanceof Smarty_Resource) {
|
if ($smarty->registered_resources[$type] instanceof Smarty_Resource) {
|
||||||
$smarty->_resource_handlers[$type] = $smarty->registered_resources[$type];
|
$smarty->_resource_handlers[$type] = $smarty->registered_resources[$type];
|
||||||
// note registered to smarty is not kept unique!
|
} else {
|
||||||
return $smarty->_resource_handlers[$type];
|
$smarty->_resource_handlers[$type] = new Smarty_Internal_Resource_Registered();
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset(self::$resources['registered'])) {
|
|
||||||
self::$resources['registered'] = new Smarty_Internal_Resource_Registered();
|
|
||||||
}
|
|
||||||
if (!isset($smarty->_resource_handlers[$type])) {
|
|
||||||
$smarty->_resource_handlers[$type] = self::$resources['registered'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $smarty->_resource_handlers[$type];
|
return $smarty->_resource_handlers[$type];
|
||||||
@@ -415,25 +170,15 @@ abstract class Smarty_Resource
|
|||||||
|
|
||||||
// try sysplugins dir
|
// try sysplugins dir
|
||||||
if (isset(self::$sysplugins[$type])) {
|
if (isset(self::$sysplugins[$type])) {
|
||||||
if (!isset(self::$resources[$type])) {
|
|
||||||
$_resource_class = 'Smarty_Internal_Resource_' . ucfirst($type);
|
$_resource_class = 'Smarty_Internal_Resource_' . ucfirst($type);
|
||||||
self::$resources[$type] = new $_resource_class();
|
return $smarty->_resource_handlers[$type] = new $_resource_class();
|
||||||
}
|
|
||||||
|
|
||||||
return $smarty->_resource_handlers[$type] = self::$resources[$type];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// try plugins dir
|
// try plugins dir
|
||||||
$_resource_class = 'Smarty_Resource_' . ucfirst($type);
|
$_resource_class = 'Smarty_Resource_' . ucfirst($type);
|
||||||
if ($smarty->loadPlugin($_resource_class)) {
|
if ($smarty->loadPlugin($_resource_class)) {
|
||||||
if (isset(self::$resources[$type])) {
|
|
||||||
return $smarty->_resource_handlers[$type] = self::$resources[$type];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (class_exists($_resource_class, false)) {
|
if (class_exists($_resource_class, false)) {
|
||||||
self::$resources[$type] = new $_resource_class();
|
return $smarty->_resource_handlers[$type] = new $_resource_class();
|
||||||
|
|
||||||
return $smarty->_resource_handlers[$type] = self::$resources[$type];
|
|
||||||
} else {
|
} else {
|
||||||
$smarty->registerResource($type, array(
|
$smarty->registerResource($type, array(
|
||||||
"smarty_resource_{$type}_source",
|
"smarty_resource_{$type}_source",
|
||||||
@@ -441,7 +186,6 @@ abstract class Smarty_Resource
|
|||||||
"smarty_resource_{$type}_secure",
|
"smarty_resource_{$type}_secure",
|
||||||
"smarty_resource_{$type}_trusted"
|
"smarty_resource_{$type}_trusted"
|
||||||
));
|
));
|
||||||
|
|
||||||
// give it another try, now that the resource is registered properly
|
// give it another try, now that the resource is registered properly
|
||||||
return self::load($smarty, $type);
|
return self::load($smarty, $type);
|
||||||
}
|
}
|
||||||
@@ -454,11 +198,7 @@ abstract class Smarty_Resource
|
|||||||
if (is_object($smarty->security_policy)) {
|
if (is_object($smarty->security_policy)) {
|
||||||
$smarty->security_policy->isTrustedStream($type);
|
$smarty->security_policy->isTrustedStream($type);
|
||||||
}
|
}
|
||||||
if (!isset(self::$resources['stream'])) {
|
return $smarty->_resource_handlers[$type] = new Smarty_Internal_Resource_Stream();;
|
||||||
self::$resources['stream'] = new Smarty_Internal_Resource_Stream();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $smarty->_resource_handlers[$type] = self::$resources['stream'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: try default_(template|config)_handler
|
// TODO: try default_(template|config)_handler
|
||||||
@@ -478,7 +218,7 @@ abstract class Smarty_Resource
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected static function parseResourceName($resource_name, $default_resource, &$name, &$type)
|
public static function parseResourceName($resource_name, $default_resource, &$name, &$type)
|
||||||
{
|
{
|
||||||
$parts = explode(':', $resource_name, 2);
|
$parts = explode(':', $resource_name, 2);
|
||||||
if (!isset($parts[1]) || !isset($parts[0][1])) {
|
if (!isset($parts[1]) || !isset($parts[0][1])) {
|
||||||
@@ -515,7 +255,7 @@ abstract class Smarty_Resource
|
|||||||
// TODO: optimize for Smarty's internal resource types
|
// TODO: optimize for Smarty's internal resource types
|
||||||
$resource = Smarty_Resource::load($template->smarty, $type);
|
$resource = Smarty_Resource::load($template->smarty, $type);
|
||||||
// go relative to a given template?
|
// go relative to a given template?
|
||||||
$_file_is_dotted = $name[0] == '.' && ($name[1] == '.' || $name[1] == '/' || $name[1] == "\\");
|
$_file_is_dotted = $name[0] == '.' && ($name[1] == '.' || $name[1] == '/');
|
||||||
if ($template instanceof Smarty_Internal_Template && $_file_is_dotted && ($template->source->type == 'file' || $template->parent->source->type == 'extends')) {
|
if ($template instanceof Smarty_Internal_Template && $_file_is_dotted && ($template->source->type == 'file' || $template->parent->source->type == 'extends')) {
|
||||||
$name = dirname($template->source->filepath) . DS . $name;
|
$name = dirname($template->source->filepath) . DS . $name;
|
||||||
}
|
}
|
||||||
@@ -524,6 +264,7 @@ abstract class Smarty_Resource
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* initialize Source Object for given resource
|
* initialize Source Object for given resource
|
||||||
|
* wrapper for backward compatibility to versions < 3.1.22
|
||||||
* Either [$_template] or [$smarty, $template_resource] must be specified
|
* Either [$_template] or [$smarty, $template_resource] must be specified
|
||||||
*
|
*
|
||||||
* @param Smarty_Internal_Template $_template template object
|
* @param Smarty_Internal_Template $_template template object
|
||||||
@@ -534,383 +275,7 @@ abstract class Smarty_Resource
|
|||||||
*/
|
*/
|
||||||
public static function source(Smarty_Internal_Template $_template = null, Smarty $smarty = null, $template_resource = null)
|
public static function source(Smarty_Internal_Template $_template = null, Smarty $smarty = null, $template_resource = null)
|
||||||
{
|
{
|
||||||
if ($_template) {
|
return Smarty_Template_Source::load($_template, $smarty, $template_resource);
|
||||||
$smarty = $_template->smarty;
|
|
||||||
$template_resource = $_template->template_resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse resource_name, load resource handler, identify unique resource name
|
|
||||||
self::parseResourceName($template_resource, $smarty->default_resource_type, $name, $type);
|
|
||||||
$resource = Smarty_Resource::load($smarty, $type);
|
|
||||||
// go relative to a given template?
|
|
||||||
$_file_is_dotted = isset($name[0]) && $name[0] == '.' && ($name[1] == '.' || $name[1] == '/' || $name[1] == "\\");
|
|
||||||
if ($_file_is_dotted && isset($_template) && $_template->parent instanceof Smarty_Internal_Template && ($_template->parent->source->type == 'file' || $_template->parent->source->type == 'extends')) {
|
|
||||||
$name2 = dirname($_template->parent->source->filepath) . DS . $name;
|
|
||||||
} else {
|
|
||||||
$name2 = $name;
|
|
||||||
}
|
|
||||||
$unique_resource_name = $resource->buildUniqueResourceName($smarty, $name2);
|
|
||||||
|
|
||||||
// check runtime cache
|
|
||||||
$_cache_key = 'template|' . $unique_resource_name;
|
|
||||||
if ($smarty->compile_id) {
|
|
||||||
$_cache_key .= '|' . $smarty->compile_id;
|
|
||||||
}
|
|
||||||
if (isset(self::$sources[$_cache_key])) {
|
|
||||||
return self::$sources[$_cache_key];
|
|
||||||
}
|
|
||||||
|
|
||||||
// create source
|
|
||||||
$source = new Smarty_Template_Source($resource, $smarty, $template_resource, $type, $name, $unique_resource_name);
|
|
||||||
$resource->populate($source, $_template);
|
|
||||||
|
|
||||||
// runtime cache
|
|
||||||
self::$sources[$_cache_key] = $source;
|
|
||||||
|
|
||||||
return $source;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* initialize Config Source Object for given resource
|
|
||||||
*
|
|
||||||
* @param Smarty_Internal_Config $_config config object
|
|
||||||
*
|
|
||||||
* @throws SmartyException
|
|
||||||
* @return Smarty_Config_Source Source Object
|
|
||||||
*/
|
|
||||||
public static function config(Smarty_Internal_Config $_config)
|
|
||||||
{
|
|
||||||
static $_incompatible_resources = array('eval' => true, 'string' => true, 'extends' => true, 'php' => true);
|
|
||||||
$config_resource = $_config->config_resource;
|
|
||||||
$smarty = $_config->smarty;
|
|
||||||
|
|
||||||
// parse resource_name
|
|
||||||
self::parseResourceName($config_resource, $smarty->default_config_type, $name, $type);
|
|
||||||
|
|
||||||
// make sure configs are not loaded via anything smarty can't handle
|
|
||||||
if (isset($_incompatible_resources[$type])) {
|
|
||||||
throw new SmartyException ("Unable to use resource '{$type}' for config");
|
|
||||||
}
|
|
||||||
|
|
||||||
// load resource handler, identify unique resource name
|
|
||||||
$resource = Smarty_Resource::load($smarty, $type);
|
|
||||||
$unique_resource_name = $resource->buildUniqueResourceName($smarty, $name, true);
|
|
||||||
|
|
||||||
// check runtime cache
|
|
||||||
$_cache_key = 'config|' . $unique_resource_name;
|
|
||||||
if (isset(self::$sources[$_cache_key])) {
|
|
||||||
return self::$sources[$_cache_key];
|
|
||||||
}
|
|
||||||
|
|
||||||
// create source
|
|
||||||
$source = new Smarty_Config_Source($resource, $smarty, $config_resource, $type, $name, $unique_resource_name);
|
|
||||||
$resource->populate($source, null);
|
|
||||||
|
|
||||||
// runtime cache
|
|
||||||
self::$sources[$_cache_key] = $source;
|
|
||||||
|
|
||||||
return $source;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Smarty Resource Data Object
|
|
||||||
* Meta Data Container for Template Files
|
|
||||||
*
|
|
||||||
* @package Smarty
|
|
||||||
* @subpackage TemplateResources
|
|
||||||
* @author Rodney Rehm
|
|
||||||
* @property integer $timestamp Source Timestamp
|
|
||||||
* @property boolean $exists Source Existence
|
|
||||||
* @property boolean $template Extended Template reference
|
|
||||||
* @property string $content Source Content
|
|
||||||
*/
|
|
||||||
class Smarty_Template_Source
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Name of the Class to compile this resource's contents with
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $compiler_class = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Name of the Class to tokenize this resource's contents with
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $template_lexer_class = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Name of the Class to parse this resource's contents with
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $template_parser_class = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unique Template ID
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $uid = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Template Resource (Smarty_Internal_Template::$template_resource)
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $resource = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resource Type
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $type = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resource Name
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $name = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unique Resource Name
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $unique_resource = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Source Filepath
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $filepath = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Source is bypassing compiler
|
|
||||||
*
|
|
||||||
* @var boolean
|
|
||||||
*/
|
|
||||||
public $uncompiled = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Source must be recompiled on every occasion
|
|
||||||
*
|
|
||||||
* @var boolean
|
|
||||||
*/
|
|
||||||
public $recompiled = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Components an extended template is made of
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public $components = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resource Handler
|
|
||||||
*
|
|
||||||
* @var Smarty_Resource
|
|
||||||
*/
|
|
||||||
public $handler = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Smarty instance
|
|
||||||
*
|
|
||||||
* @var Smarty
|
|
||||||
*/
|
|
||||||
public $smarty = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* create Source Object container
|
|
||||||
*
|
|
||||||
* @param Smarty_Resource $handler Resource Handler this source object communicates with
|
|
||||||
* @param Smarty $smarty Smarty instance this source object belongs to
|
|
||||||
* @param string $resource full template_resource
|
|
||||||
* @param string $type type of resource
|
|
||||||
* @param string $name resource name
|
|
||||||
* @param string $unique_resource unique resource name
|
|
||||||
*/
|
|
||||||
public function __construct(Smarty_Resource $handler, Smarty $smarty, $resource, $type, $name, $unique_resource)
|
|
||||||
{
|
|
||||||
$this->handler = $handler; // Note: prone to circular references
|
|
||||||
|
|
||||||
$this->compiler_class = $handler->compiler_class;
|
|
||||||
$this->template_lexer_class = $handler->template_lexer_class;
|
|
||||||
$this->template_parser_class = $handler->template_parser_class;
|
|
||||||
$this->uncompiled = $this->handler instanceof Smarty_Resource_Uncompiled;
|
|
||||||
$this->recompiled = $this->handler instanceof Smarty_Resource_Recompiled;
|
|
||||||
|
|
||||||
$this->smarty = $smarty;
|
|
||||||
$this->resource = $resource;
|
|
||||||
$this->type = $type;
|
|
||||||
$this->name = $name;
|
|
||||||
$this->unique_resource = $unique_resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get a Compiled Object of this source
|
|
||||||
*
|
|
||||||
* @param Smarty_Internal_Template|Smarty_Internal_Config $_template template object
|
|
||||||
*
|
|
||||||
* @return Smarty_Template_Compiled compiled object
|
|
||||||
*/
|
|
||||||
public function getCompiled($_template)
|
|
||||||
{
|
|
||||||
// check runtime cache
|
|
||||||
$_cache_key = $this->unique_resource . '#';
|
|
||||||
if ($_template->caching) {
|
|
||||||
$_cache_key .= 'caching#';
|
|
||||||
}
|
|
||||||
$_cache_key .= $_template->compile_id;
|
|
||||||
if (isset(Smarty_Resource::$compileds[$_cache_key])) {
|
|
||||||
return Smarty_Resource::$compileds[$_cache_key];
|
|
||||||
}
|
|
||||||
|
|
||||||
$compiled = new Smarty_Template_Compiled($this);
|
|
||||||
$this->handler->populateCompiledFilepath($compiled, $_template);
|
|
||||||
$compiled->timestamp = @filemtime($compiled->filepath);
|
|
||||||
$compiled->exists = !!$compiled->timestamp;
|
|
||||||
|
|
||||||
// runtime cache
|
|
||||||
Smarty_Resource::$compileds[$_cache_key] = $compiled;
|
|
||||||
|
|
||||||
return $compiled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* render the uncompiled source
|
|
||||||
*
|
|
||||||
* @param Smarty_Internal_Template $_template template object
|
|
||||||
*/
|
|
||||||
public function renderUncompiled(Smarty_Internal_Template $_template)
|
|
||||||
{
|
|
||||||
return $this->handler->renderUncompiled($this, $_template);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <<magic>> Generic Setter.
|
|
||||||
*
|
|
||||||
* @param string $property_name valid: timestamp, exists, content, template
|
|
||||||
* @param mixed $value new value (is not checked)
|
|
||||||
*
|
|
||||||
* @throws SmartyException if $property_name is not valid
|
|
||||||
*/
|
|
||||||
public function __set($property_name, $value)
|
|
||||||
{
|
|
||||||
switch ($property_name) {
|
|
||||||
// regular attributes
|
|
||||||
case 'timestamp':
|
|
||||||
case 'exists':
|
|
||||||
case 'content':
|
|
||||||
// required for extends: only
|
|
||||||
case 'template':
|
|
||||||
$this->$property_name = $value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new SmartyException("invalid source property '$property_name'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <<magic>> Generic getter.
|
|
||||||
*
|
|
||||||
* @param string $property_name valid: timestamp, exists, content
|
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
* @throws SmartyException if $property_name is not valid
|
|
||||||
*/
|
|
||||||
public function __get($property_name)
|
|
||||||
{
|
|
||||||
switch ($property_name) {
|
|
||||||
case 'timestamp':
|
|
||||||
case 'exists':
|
|
||||||
$this->handler->populateTimestamp($this);
|
|
||||||
|
|
||||||
return $this->$property_name;
|
|
||||||
|
|
||||||
case 'content':
|
|
||||||
return $this->content = $this->handler->getContent($this);
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new SmartyException("source property '$property_name' does not exist.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Smarty Resource Data Object
|
|
||||||
* Meta Data Container for Template Files
|
|
||||||
*
|
|
||||||
* @package Smarty
|
|
||||||
* @subpackage TemplateResources
|
|
||||||
* @author Rodney Rehm
|
|
||||||
* @property string $content compiled content
|
|
||||||
*/
|
|
||||||
class Smarty_Template_Compiled
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Compiled Filepath
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $filepath = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compiled Timestamp
|
|
||||||
*
|
|
||||||
* @var integer
|
|
||||||
*/
|
|
||||||
public $timestamp = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compiled Existence
|
|
||||||
*
|
|
||||||
* @var boolean
|
|
||||||
*/
|
|
||||||
public $exists = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compiled Content Loaded
|
|
||||||
*
|
|
||||||
* @var boolean
|
|
||||||
*/
|
|
||||||
public $loaded = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Template was compiled
|
|
||||||
*
|
|
||||||
* @var boolean
|
|
||||||
*/
|
|
||||||
public $isCompiled = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Source Object
|
|
||||||
*
|
|
||||||
* @var Smarty_Template_Source
|
|
||||||
*/
|
|
||||||
public $source = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Metadata properties
|
|
||||||
* populated by Smarty_Internal_Template::decodeProperties()
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public $_properties = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* create Compiled Object container
|
|
||||||
*
|
|
||||||
* @param Smarty_Template_Source $source source object this compiled object belongs to
|
|
||||||
*/
|
|
||||||
public function __construct(Smarty_Template_Source $source)
|
|
||||||
{
|
|
||||||
$this->source = $source;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -88,7 +88,7 @@ abstract class Smarty_Resource_Custom extends Smarty_Resource
|
|||||||
*
|
*
|
||||||
* @return string resource's basename
|
* @return string resource's basename
|
||||||
*/
|
*/
|
||||||
protected function getBasename(Smarty_Template_Source $source)
|
public function getBasename(Smarty_Template_Source $source)
|
||||||
{
|
{
|
||||||
return basename($source->name);
|
return basename($source->name);
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,13 @@
|
|||||||
*/
|
*/
|
||||||
abstract class Smarty_Resource_Recompiled extends Smarty_Resource
|
abstract class Smarty_Resource_Recompiled extends Smarty_Resource
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Flag that it's an recompiled resource
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $recompiled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* populate Compiled Object with compiled filepath
|
* populate Compiled Object with compiled filepath
|
||||||
*
|
*
|
||||||
|
@@ -16,6 +16,13 @@
|
|||||||
*/
|
*/
|
||||||
abstract class Smarty_Resource_Uncompiled extends Smarty_Resource
|
abstract class Smarty_Resource_Uncompiled extends Smarty_Resource
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Flag that it's an uncompiled resource
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $uncompiled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render and output the template (without using the compiler)
|
* Render and output the template (without using the compiler)
|
||||||
*
|
*
|
||||||
@@ -38,4 +45,25 @@ abstract class Smarty_Resource_Uncompiled extends Smarty_Resource
|
|||||||
$compiled->timestamp = false;
|
$compiled->timestamp = false;
|
||||||
$compiled->exists = false;
|
$compiled->exists = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render compiled template code
|
||||||
|
*
|
||||||
|
* @param Smarty_Internal_Template $_template
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function render($_template)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
ob_start();
|
||||||
|
$this->renderUncompiled($_template->source, $_template);
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
ob_get_clean();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
276
libs/sysplugins/smarty_template_source.php
Normal file
276
libs/sysplugins/smarty_template_source.php
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty Resource Data Object
|
||||||
|
* Meta Data Container for Template Files
|
||||||
|
*
|
||||||
|
* @package Smarty
|
||||||
|
* @subpackage TemplateResources
|
||||||
|
* @author Rodney Rehm
|
||||||
|
* @property integer $timestamp Source Timestamp
|
||||||
|
* @property boolean $exists Source Existence
|
||||||
|
* @property boolean $template Extended Template reference
|
||||||
|
* @property string $content Source Content
|
||||||
|
*/
|
||||||
|
class Smarty_Template_Source
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Name of the Class to compile this resource's contents with
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $compiler_class = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the Class to tokenize this resource's contents with
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $template_lexer_class = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the Class to parse this resource's contents with
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $template_parser_class = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unique Template ID
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $uid = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template Resource (Smarty_Internal_Template::$template_resource)
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $resource = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource Type
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $type = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource Name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $name = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unique Resource Name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $unique_resource = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source Filepath
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $filepath = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Components an extended template is made of
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $components = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource Handler
|
||||||
|
*
|
||||||
|
* @var Smarty_Resource
|
||||||
|
*/
|
||||||
|
public $handler = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty instance
|
||||||
|
*
|
||||||
|
* @var Smarty
|
||||||
|
*/
|
||||||
|
public $smarty = null;
|
||||||
|
/**
|
||||||
|
* Resource is source
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $isConfig = false;
|
||||||
|
/**
|
||||||
|
* Source is bypassing compiler
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
public $uncompiled = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source must be recompiled on every occasion
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
public $recompiled = false;
|
||||||
|
/**
|
||||||
|
* cache for Smarty_Template_Compiled instances
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $compileds = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create Source Object container
|
||||||
|
*
|
||||||
|
* @param Smarty_Resource $handler Resource Handler this source object communicates with
|
||||||
|
* @param Smarty $smarty Smarty instance this source object belongs to
|
||||||
|
* @param string $resource full template_resource
|
||||||
|
* @param string $type type of resource
|
||||||
|
* @param string $name resource name
|
||||||
|
*
|
||||||
|
* @internal param string $unique_resource unique resource name
|
||||||
|
*/
|
||||||
|
public function __construct(Smarty_Resource $handler, Smarty $smarty, $resource, $type, $name)
|
||||||
|
{
|
||||||
|
$this->handler = $handler; // Note: prone to circular references
|
||||||
|
|
||||||
|
$this->recompiled = $handler->recompiled;
|
||||||
|
$this->uncompiled = $handler->uncompiled;
|
||||||
|
$this->compiler_class = $handler->compiler_class;
|
||||||
|
$this->template_lexer_class = $handler->template_lexer_class;
|
||||||
|
$this->template_parser_class = $handler->template_parser_class;
|
||||||
|
|
||||||
|
$this->smarty = $smarty;
|
||||||
|
$this->resource = $resource;
|
||||||
|
$this->type = $type;
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initialize Source Object for given resource
|
||||||
|
* Either [$_template] or [$smarty, $template_resource] must be specified
|
||||||
|
*
|
||||||
|
* @param Smarty_Internal_Template $_template template object
|
||||||
|
* @param Smarty $smarty smarty object
|
||||||
|
* @param string $template_resource resource identifier
|
||||||
|
*
|
||||||
|
* @return Smarty_Template_Source Source Object
|
||||||
|
* @throws SmartyException
|
||||||
|
*/
|
||||||
|
public static function load(Smarty_Internal_Template $_template = null, Smarty $smarty = null, $template_resource = null)
|
||||||
|
{
|
||||||
|
if ($_template) {
|
||||||
|
$smarty = $_template->smarty;
|
||||||
|
$template_resource = $_template->template_resource;
|
||||||
|
}
|
||||||
|
if (empty($template_resource)) {
|
||||||
|
throw new SmartyException('Missing template name');
|
||||||
|
}
|
||||||
|
// parse resource_name, load resource handler, identify unique resource name
|
||||||
|
Smarty_Resource::parseResourceName($template_resource, $smarty->default_resource_type, $name, $type);
|
||||||
|
$resource = Smarty_Resource::load($smarty, $type);
|
||||||
|
// if resource is not recompiling and resource name is not dotted we can check the source cache
|
||||||
|
if ($smarty->resource_caching && !$resource->recompiled && !(isset($name[1]) && $name[0] == '.' && ($name[1] == '.' || $name[1] == '/'))) {
|
||||||
|
$unique_resource = $resource->buildUniqueResourceName($smarty, $name);
|
||||||
|
if (isset($smarty->source_objects[$unique_resource])) {
|
||||||
|
return $smarty->source_objects[$unique_resource];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$unique_resource = null;
|
||||||
|
}
|
||||||
|
// create new source object
|
||||||
|
$source = new Smarty_Template_Source($resource, $smarty, $template_resource, $type, $name);
|
||||||
|
$resource->populate($source, $_template);
|
||||||
|
if ((!isset($source->exists) || !$source->exists) && isset($_template->smarty->default_template_handler_func)) {
|
||||||
|
Smarty_Internal_Extension_DefaultTemplateHandler::_getDefault($_template, $source, $resObj);
|
||||||
|
}
|
||||||
|
// on recompiling resources we are done
|
||||||
|
if ($smarty->resource_caching && !$resource->recompiled) {
|
||||||
|
// may by we have already $unique_resource
|
||||||
|
$is_relative = false;
|
||||||
|
if (!isset($unique_resource)) {
|
||||||
|
$is_relative = isset($name[1]) && $name[0] == '.' && ($name[1] == '.' || $name[1] == '/') &&
|
||||||
|
($type == 'file' || (isset($_template->parent->source) && $_template->parent->source->type == 'extends'));
|
||||||
|
$unique_resource = $resource->buildUniqueResourceName($smarty, $is_relative ? $source->filepath . $name : $name);
|
||||||
|
}
|
||||||
|
$source->unique_resource = $unique_resource;
|
||||||
|
// save in runtime cache if not relative
|
||||||
|
if (!$is_relative) {
|
||||||
|
$smarty->source_objects[$unique_resource] = $source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $source;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render the uncompiled source
|
||||||
|
*
|
||||||
|
* @param Smarty_Internal_Template $_template template object
|
||||||
|
*/
|
||||||
|
public function renderUncompiled(Smarty_Internal_Template $_template)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
ob_start();
|
||||||
|
$this->renderUncompiled($_template->source, $_template);
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
ob_get_clean();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <<magic>> Generic Setter.
|
||||||
|
*
|
||||||
|
* @param string $property_name valid: timestamp, exists, content, template
|
||||||
|
* @param mixed $value new value (is not checked)
|
||||||
|
*
|
||||||
|
* @throws SmartyException if $property_name is not valid
|
||||||
|
*/
|
||||||
|
public function __set($property_name, $value)
|
||||||
|
{
|
||||||
|
switch ($property_name) {
|
||||||
|
// regular attributes
|
||||||
|
case 'timestamp':
|
||||||
|
case 'exists':
|
||||||
|
case 'content':
|
||||||
|
// required for extends: only
|
||||||
|
case 'template':
|
||||||
|
$this->$property_name = $value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new SmartyException("source property '$property_name' does not exist.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <<magic>> Generic getter.
|
||||||
|
*
|
||||||
|
* @param string $property_name valid: timestamp, exists, content
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @throws SmartyException if $property_name is not valid
|
||||||
|
*/
|
||||||
|
public function __get($property_name)
|
||||||
|
{
|
||||||
|
switch ($property_name) {
|
||||||
|
case 'timestamp':
|
||||||
|
case 'exists':
|
||||||
|
$this->handler->populateTimestamp($this);
|
||||||
|
|
||||||
|
return $this->$property_name;
|
||||||
|
|
||||||
|
case 'content':
|
||||||
|
return $this->content = $this->handler->getContent($this);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new SmartyException("source property '$property_name' does not exist.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user