- new extension handler to load functions when called

This commit is contained in:
uwetews
2015-10-24 05:12:10 +02:00
parent 888014b908
commit 0ea1360d65
9 changed files with 3 additions and 752 deletions

View File

@@ -1,4 +1,7 @@
 ===== 3.1.28-dev===== (xx.xx.2015)
24.10.2015
- new extension handler to load functions when called
21.10.2015
- move some code into runtime extensions

View File

@@ -1,88 +0,0 @@
<?php
/**
* Smarty Extension Append
*
* getStreamVariable() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Extension_Append
{
/**
* appends values to template variables
*
* @param array|string $tpl_var the template variable name(s)
* @param mixed $value the value to append
* @param boolean $merge flag if array elements shall be merged
* @param boolean $nocache if true any output of this variable will be not cached
*
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
*/
public static function append($obj, $tpl_var, $value, $merge, $nocache)
{
if (is_array($tpl_var)) {
// $tpl_var is an array, ignore $value
foreach ($tpl_var as $_key => $_val) {
if ($_key != '') {
self::append($obj, $_key, $_val, $merge, $nocache);
}
}
} else {
if ($tpl_var != '' && isset($value)) {
if (!isset($obj->tpl_vars[$tpl_var])) {
$tpl_var_inst = Smarty_Internal_Extension_GetVars::getVariable($obj, $tpl_var, null, true, false);
if ($tpl_var_inst instanceof Smarty_Undefined_Variable) {
$obj->tpl_vars[$tpl_var] = new Smarty_Variable(null, $nocache);
} else {
$obj->tpl_vars[$tpl_var] = clone $tpl_var_inst;
}
}
if (!(is_array($obj->tpl_vars[$tpl_var]->value) || $obj->tpl_vars[$tpl_var]->value instanceof ArrayAccess)) {
settype($obj->tpl_vars[$tpl_var]->value, 'array');
}
if ($merge && is_array($value)) {
foreach ($value as $_mkey => $_mval) {
$obj->tpl_vars[$tpl_var]->value[$_mkey] = $_mval;
}
} else {
$obj->tpl_vars[$tpl_var]->value[] = $value;
}
}
}
return $obj;
}
/**
* appends values to template variables by reference
*
* @param string $tpl_var the template variable name
* @param mixed &$value the referenced value to append
* @param boolean $merge flag if array elements shall be merged
*
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
*/
public static function appendByRef($obj, $tpl_var, &$value, $merge)
{
if ($tpl_var != '' && isset($value)) {
if (!isset($obj->tpl_vars[$tpl_var])) {
$obj->tpl_vars[$tpl_var] = new Smarty_Variable();
}
if (!is_array($obj->tpl_vars[$tpl_var]->value)) {
settype($obj->tpl_vars[$tpl_var]->value, 'array');
}
if ($merge && is_array($value)) {
foreach ($value as $_key => $_val) {
$obj->tpl_vars[$tpl_var]->value[$_key] = &$value[$_key];
}
} else {
$obj->tpl_vars[$tpl_var]->value[] = &$value;
}
}
return $obj;
}
}

View File

@@ -1,102 +0,0 @@
<?php
/**
* Smarty Extension AutoLoadFilter
*
* Auto load filter methods
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Extension_AutoLoadFilter
{
/**
* Valid filter types
*
* @var array
*/
static $filterTypes = array('pre' => true, 'post' => true, 'output' => true, 'variable' => true);
/**
* Set autoload filters
*
* @param \Smarty $smarty
* @param array $filters filters to load automatically
* @param string $type "pre", "output", <20> specify the filter type to set. Defaults to none treating $filters'
* keys as the appropriate types
*/
public static function setAutoloadFilters(Smarty $smarty, $filters, $type)
{
if ($type !== null) {
self::_checkFilterType($type);
$smarty->autoload_filters[$type] = (array) $filters;
} else {
foreach ((array) $filters as $type => $value) {
self::_checkFilterType($type);
}
$smarty->autoload_filters = (array) $filters;
}
}
/**
* Add autoload filters
*
* @param \Smarty $smarty
* @param array $filters filters to load automatically
* @param string $type "pre", "output", <20> specify the filter type to set. Defaults to none treating $filters'
* keys as the appropriate types
*/
public static function addAutoloadFilters(Smarty $smarty, $filters, $type)
{
if ($type !== null) {
self::_checkFilterType($type);
if (!empty($smarty->autoload_filters[$type])) {
$smarty->autoload_filters[$type] = array_merge($smarty->autoload_filters[$type], (array) $filters);
} else {
$smarty->autoload_filters[$type] = (array) $filters;
}
} else {
foreach ((array) $filters as $type => $value) {
self::_checkFilterType($type);
if (!empty($smarty->autoload_filters[$type])) {
$smarty->autoload_filters[$type] = array_merge($smarty->autoload_filters[$type], (array) $value);
} else {
$smarty->autoload_filters[$type] = (array) $value;
}
}
}
}
/**
* Get autoload filters
*
* @param \Smarty $smarty
* @param string $type type of filter to get auto loads for. Defaults to all autoload filters
*
* @return array array( 'type1' => array( 'filter1', 'filter2', <20> ) ) or array( 'filter1', 'filter2', <20>) if $type
* was specified
*/
public static function getAutoloadFilters(Smarty $smarty, $type)
{
if ($type !== null) {
self::_checkFilterType($type);
return isset($smarty->autoload_filters[$type]) ? $smarty->autoload_filters[$type] : array();
}
return $smarty->autoload_filters;
}
/**
* Check if filter type is valid
*
* @param string $type
*
* @throws \SmartyException
*/
static function _checkFilterType($type)
{
if (!isset(self::$filterTypes[$type])) {
throw new SmartyException("Illegal filter type \"{$type}\"");
}
}
}

View File

@@ -1,85 +0,0 @@
<?php
/**
* Smarty Internal Extension
* This file contains the Smarty template extension to create a code frame
*
* @package Smarty
* @subpackage Template
* @author Uwe Tews
*/
/**
* Class Smarty_Internal_Extension_CodeFrame
* Create code frame for compiled and cached templates
*/
class Smarty_Internal_Extension_CodeFrame
{
/**
* Create code frame for compiled and cached templates
*
* @param Smarty_Internal_Template $_template
* @param string $content optional template content
* @param bool $cache flag for cache file
*
* @return string
*/
public static function create(Smarty_Internal_Template $_template, $content = '', $functions = '', $cache = false)
{
// build property code
$properties['has_nocache_code'] = $_template->compiled->has_nocache_code;
$properties['version'] = Smarty::SMARTY_VERSION;
$properties['unifunc'] = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
if (!empty($_template->tpl_function)) {
$properties['tpl_function'] = $_template->tpl_function;
}
if (!$cache) {
$properties['file_dependency'] = $_template->compiled->file_dependency;
$properties['includes'] = $_template->compiled->includes;
} else {
$properties['file_dependency'] = $_template->cached->file_dependency;
$properties['cache_lifetime'] = $_template->cache_lifetime;
}
$output = "<?php\n";
$output .= "\$_valid = \$_smarty_tpl->decodeProperties(" . var_export($properties, true) . ',' .
($cache ? 'true' : 'false') . ");\n";
$output .= "if (\$_valid && !is_callable('{$properties['unifunc']}')) {\n";
$output .= "function {$properties['unifunc']} (\$_smarty_tpl) {\n";
// include code for plugins
if (!$cache) {
if (!empty($_template->compiled->required_plugins['compiled'])) {
foreach ($_template->compiled->required_plugins['compiled'] as $tmp) {
foreach ($tmp as $data) {
$file = addslashes($data['file']);
if (is_array($data['function'])) {
$output .= "if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) require_once '{$file}';\n";
} else {
$output .= "if (!is_callable('{$data['function']}')) require_once '{$file}';\n";
}
}
}
}
if ($_template->caching && !empty($_template->compiled->required_plugins['nocache'])) {
$_template->compiled->has_nocache_code = true;
$output .= "echo '/*%%SmartyNocache:{$_template->compiled->nocache_hash}%%*/<?php \$_smarty = \$_smarty_tpl->smarty; ";
foreach ($_template->compiled->required_plugins['nocache'] as $tmp) {
foreach ($tmp as $data) {
$file = addslashes($data['file']);
if (is_Array($data['function'])) {
$output .= addslashes("if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) require_once '{$file}';\n");
} else {
$output .= addslashes("if (!is_callable('{$data['function']}')) require_once '{$file}';\n");
}
}
}
$output .= "?>/*/%%SmartyNocache:{$_template->compiled->nocache_hash}%%*/';\n";
}
}
$output .= "?>\n";
$output .= $content;
$output .= "<?php }\n?>";
$output .= $functions;
$output .= "<?php }\n";
// remove unneeded PHP tags
return preg_replace('/\s*\?>[\n]?<\?php\s/', "\n", $output);
}
}

View File

@@ -1,30 +0,0 @@
<?php
/**
* Smarty Extension Hhvm
*
* include patch for modified compiled or cached templates
* HHVM does not check if file was modified when including same file multiple times
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Extension_Hhvm
{
/**
* @param \Smarty_Internal_Template $_template
* @param string $file file name
*
* @return mixed
*/
static function includeHhvm(Smarty_Internal_Template $_template, $file)
{
$_smarty_tpl = $_template;
$tmp_file = $file . preg_replace('![^\w]+!', '_', uniqid(rand(), true)) . '.php';
file_put_contents($tmp_file, file_get_contents($file));
$result = @include $tmp_file;
@unlink($tmp_file);
return $result;
}
}

View File

@@ -1,106 +0,0 @@
<?php
/**
* Smarty Extension Loadplugin
*
* $smarty->loadPlugin() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Extension_LoadPlugin
{
/**
* Takes unknown classes and loads plugin files for them
* class name format: Smarty_PluginType_PluginName
* plugin filename format: plugintype.pluginname.php
*
* @param \Smarty $smarty
* @param string $plugin_name class plugin name to load
* @param bool $check check if already loaded
*
* @return bool|string
* @throws \SmartyException
*/
public static function loadPlugin(Smarty $smarty, $plugin_name, $check)
{
// if function or class exists, exit silently (already loaded)
if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) {
return true;
}
if (!preg_match('#^smarty_((internal)|([^_]+))_(.+)$#i', $plugin_name, $match)) {
throw new SmartyException("plugin {$plugin_name} is not a valid name format");
}
if (!empty($match[2])) {
$file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php';
if (isset($smarty->_cache['plugin_files'][$file])) {
if ($smarty->_cache['plugin_files'][$file] !== false) {
return $smarty->_cache['plugin_files'][$file];
} else {
return false;
}
} else {
if (is_file($file)) {
$smarty->_cache['plugin_files'][$file] = $file;
require_once($file);
return $file;
} else {
$smarty->_cache['plugin_files'][$file] = false;
return false;
}
}
}
// plugin filename is expected to be: [type].[name].php
$_plugin_filename = "{$match[1]}.{$match[4]}.php";
$_lower_filename = strtolower($_plugin_filename);
if (isset($smarty->_cache['plugin_files'])) {
if (isset($smarty->_cache['plugin_files']['plugins_dir'][$_lower_filename])) {
if (!$smarty->use_include_path ||
$smarty->_cache['plugin_files']['plugins_dir'][$_lower_filename] !== false
) {
return $smarty->_cache['plugin_files']['plugins_dir'][$_lower_filename];
}
}
if (!$smarty->use_include_path || Smarty_Internal_Get_Include_Path::isNewIncludePath($smarty)) {
unset($smarty->_cache['plugin_files']['include_path']);
} else {
if (isset($smarty->_cache['plugin_files']['include_path'][$_lower_filename])) {
return $smarty->_cache['plugin_files']['include_path'][$_lower_filename];
}
}
}
$_file_names = array($_plugin_filename);
if ($_lower_filename != $_plugin_filename) {
$_file_names[] = $_lower_filename;
}
$_p_dirs = $smarty->getPluginsDir();
if (!isset($smarty->_cache['plugin_files']['plugins_dir'][$_lower_filename])) {
// loop through plugin dirs and find the plugin
foreach ($_p_dirs as $_plugin_dir) {
foreach ($_file_names as $name) {
$file = $_plugin_dir . $name;
if (is_file($file)) {
$smarty->_cache['plugin_files']['plugins_dir'][$_lower_filename] = $file;
require_once($file);
return $file;
}
$smarty->_cache['plugin_files']['plugins_dir'][$_lower_filename] = false;
}
}
}
if ($smarty->use_include_path) {
foreach ($_file_names as $_file_name) {
// try PHP include_path
$file = Smarty_Internal_Get_Include_Path::getIncludePath($_p_dirs, $_file_name, $smarty);
$smarty->_cache['plugin_files']['include_path'][$_lower_filename] = $file;
if ($file !== false) {
require_once($file);
return $file;
}
}
}
// no plugin loaded
return false;
}
}

View File

@@ -1,69 +0,0 @@
<?php
/**
* Smarty Internal Plugin Filter Handler
* Smarty filter handler class
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
/**
* Class for filter processing
*
* @package Smarty
* @subpackage PluginsInternal
*/
class Smarty_Internal_Filter_Handler
{
/**
* Run filters over content
* The filters will be lazy loaded if required
* class name format: Smarty_FilterType_FilterName
* plugin filename format: filtertype.filtername.php
* Smarty2 filter plugins could be used
*
* @param string $type the type of filter ('pre','post','output') which shall run
* @param string $content the content which shall be processed by the filters
* @param Smarty_Internal_Template $template template object
*
* @throws SmartyException
* @return string the filtered content
*/
public static function runFilter($type, $content, Smarty_Internal_Template $template)
{
// loop over autoload filters of specified type
if (!empty($template->smarty->autoload_filters[$type])) {
foreach ((array) $template->smarty->autoload_filters[$type] as $name) {
$plugin_name = "Smarty_{$type}filter_{$name}";
if (function_exists($plugin_name)) {
$callback = $plugin_name;
} elseif (class_exists($plugin_name, false) && is_callable(array($plugin_name, 'execute'))) {
$callback = array($plugin_name, 'execute');
} elseif ($template->smarty->loadPlugin($plugin_name, false)) {
if (function_exists($plugin_name)) {
// use loaded Smarty2 style plugin
$callback = $plugin_name;
} elseif (class_exists($plugin_name, false) && is_callable(array($plugin_name, 'execute'))) {
// loaded class of filter plugin
$callback = array($plugin_name, 'execute');
} else {
throw new SmartyException("Auto load {$type}-filter plugin method \"{$plugin_name}::execute\" not callable");
}
} else {
// nothing found, throw exception
throw new SmartyException("Unable to auto load {$type}-filter plugin \"{$plugin_name}\"");
}
$content = call_user_func($callback, $content, $template);
}
}
// loop over registered filters of specified type
if (!empty($template->smarty->registered_filters[$type])) {
foreach ($template->smarty->registered_filters[$type] as $key => $name) {
$content = call_user_func($template->smarty->registered_filters[$type][$key], $content, $template);
}
}
// return filtered output
return $content;
}
}

View File

@@ -1,182 +0,0 @@
<?php
/**
* Smarty read include path plugin
*
* @package Smarty
* @subpackage PluginsInternal
* @author Monte Ohrt
*/
/**
* Smarty Internal Read Include Path Class
*
* @package Smarty
* @subpackage PluginsInternal
*/
class Smarty_Internal_Get_Include_Path
{
/**
* include path cache
*
* @var string
*/
static $_include_path = '';
/**
* include path directory cache
*
* @var array
*/
static $_include_dirs = array();
/**
* include path directory cache
*
* @var array
*/
static $_user_dirs = array();
/**
* stream cache
*
* @var string[]
*/
static $isFile = array();
/**
* stream cache
*
* @var string[]
*/
static $isPath = array();
/**
* stream cache
*
* @var int[]
*/
static $number = array();
/**
* status cache
*
* @var bool
*/
static $_has_stream_include = null;
/**
* Number for array index
*
* @var int
*/
static $counter = 0;
/**
* Check if include path was updated
*
* @param \Smarty $smarty
*
* @return bool
*/
public static function isNewIncludePath(Smarty $smarty)
{
$_i_path = get_include_path();
if (self::$_include_path != $_i_path) {
self::$_include_dirs = array();
self::$_include_path = $_i_path;
$_dirs = (array) explode(PATH_SEPARATOR, $_i_path);
foreach ($_dirs as $_path) {
if ($_path[0] != '/' && isset($dir[1]) && $dir[1] != ':') {
$_path = $smarty->_realpath($_path . DS, true);
}
if (is_dir($_path)) {
self::$_include_dirs[] = $smarty->_realpath($_path . DS, true);
}
}
return true;
}
return false;
}
/**
* return array with include path directories
*
* @param \Smarty $smarty
*
* @return array
*/
public static function getIncludePathDirs(Smarty $smarty)
{
Smarty_Internal_Get_Include_Path::isNewIncludePath($smarty);
return self::$_include_dirs;
}
/**
* Return full file path from PHP include_path
*
* @param string[] $dirs
* @param string $file
* @param \Smarty $smarty
*
* @return bool|string full filepath or false
*
*/
public static function getIncludePath($dirs, $file, Smarty $smarty)
{
if (!(isset(self::$_has_stream_include) ? self::$_has_stream_include : self::$_has_stream_include = function_exists('stream_resolve_include_path'))) {
self::isNewIncludePath($smarty);
}
// try PHP include_path
foreach ($dirs as $dir) {
$dir_n = isset(self::$number[$dir]) ? self::$number[$dir] : self::$number[$dir] = self::$counter ++;
if (isset(self::$isFile[$dir_n][$file])) {
if (self::$isFile[$dir_n][$file]) {
return self::$isFile[$dir_n][$file];
} else {
continue;
}
}
if (isset(self::$_user_dirs[$dir_n])) {
if (false === self::$_user_dirs[$dir_n]) {
continue;
} else {
$dir = self::$_user_dirs[$dir_n];
}
} else {
if ($dir[0] == '/' || $dir[1] == ':') {
$dir = str_ireplace(getcwd(), '.', $dir);
if ($dir[0] == '/' || $dir[1] == ':') {
self::$_user_dirs[$dir_n] = false;
continue;
}
}
$dir = substr($dir, 2);
self::$_user_dirs[$dir_n] = $dir;
}
if (self::$_has_stream_include) {
$path = stream_resolve_include_path($dir . (isset($file) ? $file : ''));
if ($path) {
return self::$isFile[$dir_n][$file] = $path;
}
} else {
foreach (self::$_include_dirs as $key => $_i_path) {
$path = isset(self::$isPath[$key][$dir_n]) ? self::$isPath[$key][$dir_n] : self::$isPath[$key][$dir_n] = is_dir($_dir_path = $_i_path .
$dir) ? $_dir_path : false;
if ($path === false) {
continue;
}
if (isset($file)) {
$_file = self::$isFile[$dir_n][$file] = (is_file($path . $file)) ? $path . $file : false;
if ($_file) {
return $_file;
}
} else {
// no file was given return directory path
return $path;
}
}
}
}
return false;
}
}

View File

@@ -1,90 +0,0 @@
<?php
/**
* Smarty write file plugin
*
* @package Smarty
* @subpackage PluginsInternal
* @author Monte Ohrt
*/
/**
* Smarty Internal Write File Class
*
* @package Smarty
* @subpackage PluginsInternal
*/
class Smarty_Internal_Write_File
{
/**
* Writes file in a safe way to disk
*
* @param string $_filepath complete filepath
* @param string $_contents file content
* @param Smarty $smarty smarty instance
*
* @throws SmartyException
* @return boolean true
*/
public function writeFile($_filepath, $_contents, Smarty $smarty)
{
$_error_reporting = error_reporting();
error_reporting($_error_reporting & ~E_NOTICE & ~E_WARNING);
$_file_perms = property_exists($smarty, '_file_perms') ? $smarty->_file_perms : 0644;
$_dir_perms = property_exists($smarty, '_dir_perms') ? (isset($smarty->_dir_perms) ? $smarty->_dir_perms : 0777) : 0771;
if ($_file_perms !== null) {
$old_umask = umask(0);
}
$_dirpath = dirname($_filepath);
// if subdirs, create dir structure
if ($_dirpath !== '.' && !file_exists($_dirpath)) {
mkdir($_dirpath, $_dir_perms, true);
}
// write to tmp file, then move to overt file lock race condition
$_tmp_file = $_dirpath . DS . str_replace(array('.', ','), '_', uniqid('wrt', true));
if (!file_put_contents($_tmp_file, $_contents)) {
error_reporting($_error_reporting);
throw new SmartyException("unable to write file {$_tmp_file}");
}
/*
* Windows' rename() fails if the destination exists,
* Linux' rename() properly handles the overwrite.
* Simply unlink()ing a file might cause other processes
* currently reading that file to fail, but linux' rename()
* seems to be smart enough to handle that for us.
*/
if (Smarty::$_IS_WINDOWS) {
// remove original file
if (is_file($_filepath)) {
@unlink($_filepath);
}
// rename tmp file
$success = @rename($_tmp_file, $_filepath);
} else {
// rename tmp file
$success = @rename($_tmp_file, $_filepath);
if (!$success) {
// remove original file
if (is_file($_filepath)) {
@unlink($_filepath);
}
// rename tmp file
$success = @rename($_tmp_file, $_filepath);
}
}
if (!$success) {
error_reporting($_error_reporting);
throw new SmartyException("unable to write file {$_filepath}");
}
if ($_file_perms !== null) {
// set file permissions
chmod($_filepath, $_file_perms);
umask($old_umask);
}
error_reporting($_error_reporting);
return true;
}
}