diff options
Diffstat (limited to 'libs/Smarty.class.php')
| -rw-r--r-- | libs/Smarty.class.php | 1570 |
1 files changed, 1028 insertions, 542 deletions
diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 6c9b7489..3e3492a9 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -1,71 +1,75 @@ <?php - /** - * Project: Smarty: the PHP compiling template engine - * File: Smarty.class.php - * SVN: $Id$ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * For questions, help, comments, discussion, etc., please join the - * Smarty mailing list. Send a blank e-mail to - * smarty-discussion-subscribe@googlegroups.com - * - * @link http://www.smarty.net/ - * @copyright 2008 New Digital Group, Inc. - * @author Monte Ohrt <monte at ohrt dot com> - * @author Uwe Tews - * @package Smarty - * @version 3-SVN$Rev: 3286 $ - */ +* Project: Smarty: the PHP compiling template engine +* File: Smarty.class.php +* SVN: $Id$ +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* For questions, help, comments, discussion, etc., please join the +* Smarty mailing list. Send a blank e-mail to +* smarty-discussion-subscribe@googlegroups.com +* +* @link http://www.smarty.net/ +* @copyright 2008 New Digital Group, Inc. +* @author Monte Ohrt <monte at ohrt dot com> +* @author Uwe Tews +* @author Rodney Rehm +* @package Smarty +* @version 3.1-DEV +*/ /** - * define shorthand directory separator constant - */ +* define shorthand directory separator constant +*/ if (!defined('DS')) { define('DS', DIRECTORY_SEPARATOR); } /** - * set SMARTY_DIR to absolute path to Smarty library files. - * Sets SMARTY_DIR only if user application has not already defined it. - */ +* set SMARTY_DIR to absolute path to Smarty library files. +* Sets SMARTY_DIR only if user application has not already defined it. +*/ if (!defined('SMARTY_DIR')) { define('SMARTY_DIR', dirname(__FILE__) . DS); } /** - * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins. - * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it. - */ +* set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins. +* Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it. +*/ if (!defined('SMARTY_SYSPLUGINS_DIR')) { define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DS); } if (!defined('SMARTY_PLUGINS_DIR')) { define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS); } +if (!defined('SMARTY_MBSTRING')) { + define('SMARTY_MBSTRING', function_exists('mb_strlen')); +} if (!defined('SMARTY_RESOURCE_CHAR_SET')) { - define('SMARTY_RESOURCE_CHAR_SET', 'UTF-8'); + // UTF-8 can only be done properly when mbstring is available! + define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1'); } if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) { define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y'); } /** - * register the class autoloader - */ +* register the class autoloader +*/ if (!defined('SMARTY_SPL_AUTOLOAD')) { define('SMARTY_SPL_AUTOLOAD', 0); } @@ -80,176 +84,465 @@ if (SMARTY_SPL_AUTOLOAD && set_include_path(get_include_path() . PATH_SEPARATOR } /** - * This is the main Smarty class - */ -class Smarty extends Smarty_Internal_Data { - /** - * constant definitions - */ - // smarty version - const SMARTY_VERSION = 'Smarty3-SVN$Rev: 3286 $'; - //define variable scopes - const SCOPE_LOCAL = 0; - const SCOPE_PARENT = 1; - const SCOPE_ROOT = 2; - const SCOPE_GLOBAL = 3; - // define caching modes - const CACHING_OFF = 0; - const CACHING_LIFETIME_CURRENT = 1; - const CACHING_LIFETIME_SAVED = 2; - /** modes for handling of "<?php ... ?>" tags in templates. **/ - const PHP_PASSTHRU = 0; //-> print tags as plain text - const PHP_QUOTE = 1; //-> escape tags as entities - const PHP_REMOVE = 2; //-> escape tags as entities - const PHP_ALLOW = 3; //-> escape tags as entities - // filter types - const FILTER_POST = 'post'; - const FILTER_PRE = 'pre'; - const FILTER_OUTPUT = 'output'; - const FILTER_VARIABLE = 'variable'; - // plugin types - const PLUGIN_FUNCTION = 'function'; - const PLUGIN_BLOCK = 'block'; - const PLUGIN_COMPILER = 'compiler'; - const PLUGIN_MODIFIER = 'modifier'; +* Load always needed external class files +*/ +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_data.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_templatebase.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_template.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_resource.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_resource_file.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_cacheresource.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_cacheresource_file.php'; - /** - * static variables - */ - // assigned global tpl vars - static $global_tpl_vars = array(); +/** +* This is the main Smarty class +* @package Smarty +*/ +class Smarty extends Smarty_Internal_TemplateBase { + + /**#@+ + * constant definitions + */ - /** - * variables - */ - // auto literal on delimiters with whitspace + /** + * smarty version + */ + const SMARTY_VERSION = 'Smarty 3.1-DEV'; + + /** + * define variable scopes + */ + const SCOPE_LOCAL = 0; + const SCOPE_PARENT = 1; + const SCOPE_ROOT = 2; + const SCOPE_GLOBAL = 3; + /** + * define caching modes + */ + const CACHING_OFF = 0; + const CACHING_LIFETIME_CURRENT = 1; + const CACHING_LIFETIME_SAVED = 2; + /** + * define compile check modes + */ + const COMPILECHECK_OFF = 0; + const COMPILECHECK_ON = 1; + const COMPILECHECK_CACHEMISS = 2; + /** + * modes for handling of "<?php ... ?>" tags in templates. + */ + const PHP_PASSTHRU = 0; //-> print tags as plain text + const PHP_QUOTE = 1; //-> escape tags as entities + const PHP_REMOVE = 2; //-> escape tags as entities + const PHP_ALLOW = 3; //-> escape tags as entities + /** + * filter types + */ + const FILTER_POST = 'post'; + const FILTER_PRE = 'pre'; + const FILTER_OUTPUT = 'output'; + const FILTER_VARIABLE = 'variable'; + /** + * plugin types + */ + const PLUGIN_FUNCTION = 'function'; + const PLUGIN_BLOCK = 'block'; + const PLUGIN_COMPILER = 'compiler'; + const PLUGIN_MODIFIER = 'modifier'; + const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler'; + + /**#@-*/ + + /** + * assigned global tpl vars + */ + public static $global_tpl_vars = array(); + + /**#@+ + * variables + */ + + /** + * auto literal on delimiters with whitspace + * @var boolean + */ public $auto_literal = true; - // display error on not assigned variables + /** + * display error on not assigned variables + * @var boolean + */ public $error_unassigned = false; - // template directory - public $template_dir = null; - // default template handler + /** + * look up relative filepaths in include_path + * @var boolean + */ + public $use_include_path = false; + /** + * template directory + * @var string + */ + protected $template_dir = null; + /** + * default template handler + * @var callable + */ public $default_template_handler_func = null; - // compile directory - public $compile_dir = null; - // plugins directory - public $plugins_dir = null; - // cache directory - public $cache_dir = null; - // config directory - public $config_dir = null; - // force template compiling? + /** + * default config handler + * @var callable + */ + public $default_config_handler_func = null; + /** + * default plugin handler + * @var callable + */ + public $default_plugin_handler_func = null; + /** + * compile directory + * @var string + */ + protected $compile_dir = null; + /** + * plugins directory + * @var string + */ + protected $plugins_dir = null; + /** + * cache directory + * @var string + */ + protected $cache_dir = null; + /** + * config directory + * @var string + */ + protected $config_dir = null; + /** + * force template compiling? + * @var boolean + */ public $force_compile = false; - // check template for modifications? + /** + * check template for modifications? + * @var boolean + */ public $compile_check = true; - // locking concurrent compiles - public $compile_locking = true; - // use sub dirs for compiled/cached files? + /** + * use sub dirs for compiled/cached files? + * @var boolean + */ public $use_sub_dirs = false; - // compile_error? - public $compile_error = false; - // caching enabled + /** + * caching enabled + * @var boolean + */ public $caching = false; - // merge compiled includes + /** + * merge compiled includes + * @var boolean + */ public $merge_compiled_includes = false; - // cache lifetime + /** + * cache lifetime in seconds + * @var integer + */ public $cache_lifetime = 3600; - // force cache file creation + /** + * force cache file creation + * @var boolean + */ public $force_cache = false; - // cache_id + /** + * Set this if you want different sets of cache files for the same + * templates. + * + * @var string + */ public $cache_id = null; - // compile_id + /** + * Set this if you want different sets of compiled files for the same + * templates. + * + * @var string + */ public $compile_id = null; - // template delimiters + /** + * template left-delimiter + * @var string + */ public $left_delimiter = "{"; + /** + * template right-delimiter + * @var string + */ public $right_delimiter = "}"; - // security + /**#@+ + * security + */ + /** + * class name + * + * This should be instance of Smarty_Security. + * + * @var string + * @see Smarty_Security + */ public $security_class = 'Smarty_Security'; + /** + * implementation of security class + * + * @var Smarty_Security + */ public $security_policy = null; + /** + * controls handling of PHP-blocks + * + * @var integer + */ public $php_handling = self::PHP_PASSTHRU; - public $allow_php_tag = false; + /** + * controls if the php template file resource is allowed + * + * @var bool + */ public $allow_php_templates = false; + /** + * Should compiled-templates be prevented from being called directly? + * + * {@internal + * Currently used by Smarty_Internal_Template only. + * }} + * + * @var boolean + */ public $direct_access_security = true; - public $trusted_dir = array(); - // debug mode + /**#@-*/ + /** + * debug mode + * + * Setting this to true enables the debug-console. + * + * @var boolean + */ public $debugging = false; + /** + * This determines if debugging is enable-able from the browser. + * <ul> + * <li>NONE => no debugging control allowed</li> + * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li> + * </ul> + * @var string + */ public $debugging_ctrl = 'NONE'; + /** + * Name of debugging URL-param. + * + * Only used when $debugging_ctrl is set to 'URL'. + * The name of the URL-parameter that activates debugging. + * + * @var type + */ public $smarty_debug_id = 'SMARTY_DEBUG'; + /** + * Path of debug template. + * @var string + */ public $debug_tpl = null; - // When set, smarty does uses this value as error_reporting-level. + /** + * When set, smarty uses this value as error_reporting-level. + * @var int + */ public $error_reporting = null; - // config var settings - public $config_overwrite = true; //Controls whether variables with the same name overwrite each other. - public $config_booleanize = true; //Controls whether config values of on/true/yes and off/false/no get converted to boolean - public $config_read_hidden = false; //Controls whether hidden config sections/vars are read from the file. - // config vars - public $config_vars = array(); - // assigned tpl vars - public $tpl_vars = array(); - // dummy parent object - public $parent = null; - // global template functions + /** + * Internal flag for getTags() + * @var boolean + */ + public $get_used_tags = false; + + /**#@+ + * config var settings + */ + + /** + * Controls whether variables with the same name overwrite each other. + * @var boolean + */ + public $config_overwrite = true; + /** + * Controls whether config values of on/true/yes and off/false/no get converted to boolean. + * @var boolean + */ + public $config_booleanize = true; + /** + * Controls whether hidden config sections/vars are read from the file. + * @var boolean + */ + public $config_read_hidden = false; + + /**#@-*/ + + /**#@+ + * resource locking + */ + + /** + * locking concurrent compiles + * @var boolean + */ + public $compile_locking = true; + /** + * Controls whether cache resources should emply locking mechanism + * @var boolean + */ + public $cache_locking = false; + /** + * seconds to wait for acquiring a lock before ignoring the write lock + * @var float + */ + public $locking_timeout = 10; + + /**#@-*/ + + /** + * global template functions + * @var array + */ public $template_functions = array(); - // resource type used if none given + /** + * resource type used if none given + * + * Must be an valid key of $registered_resources. + * @var string + */ public $default_resource_type = 'file'; - // caching type + /** + * caching type + * + * Must be an element of $cache_resource_types. + * + * @var string + */ public $caching_type = 'file'; - // internal cache resource types - public $cache_resource_types = array('file'); - // internal config properties + /** + * internal config properties + * @var array + */ public $properties = array(); - // config type + /** + * config type + * @var string + */ public $default_config_type = 'file'; - // cached template objects - public $template_objects = null; - // check If-Modified-Since headers + /** + * cached template objects + * @var array + */ + public $template_objects = array(); + /** + * check If-Modified-Since headers + * @var boolean + */ public $cache_modified_check = false; - // registered plugins + /** + * registered plugins + * @var array + */ public $registered_plugins = array(); - // plugin search order + /** + * plugin search order + * @var array + */ public $plugin_search_order = array('function', 'block', 'compiler', 'class'); - // registered objects + /** + * registered objects + * @var array + */ public $registered_objects = array(); - // registered classes + /** + * registered classes + * @var array + */ public $registered_classes = array(); - // registered filters + /** + * registered filters + * @var array + */ public $registered_filters = array(); - // registered resources + /** + * registered resources + * @var array + */ public $registered_resources = array(); - // autoload filter + /** + * registered cache resources + * @var array + */ + public $registered_cache_resources = array(); + /** + * autoload filter + * @var array + */ public $autoload_filters = array(); - // status of filter on variable output - public $variable_filter = true; - // default modifier + /** + * default modifier + * @var array + */ public $default_modifiers = array(); - // global internal smarty vars - static $_smarty_vars = array(); - // start time for execution time calculation + /** + * autoescape variable output + * @var boolean + */ + public $escape_html = false; + /** + * global internal smarty vars + * @var array + */ + public static $_smarty_vars = array(); + /** + * start time for execution time calculation + * @var int + */ public $start_time = 0; - // default file permissions + /** + * default file permissions + * @var int + */ public $_file_perms = 0644; - // default dir permissions + /** + * default dir permissions + * @var int + */ public $_dir_perms = 0771; - // block tag hierarchy + /** + * block tag hierarchy + * @var array + */ public $_tag_stack = array(); - // flag if {block} tag is compiled for template inheritance - public $inheritance = false; - // generate deprecated function call notices? - public $deprecation_notices = true; - // internal flag for getTags() - public $get_used_tags = false; - // Smarty 2 BC - public $_version = self::SMARTY_VERSION; - // self pointer to Smarty object + /** + * self pointer to Smarty object + * @var Smarty + */ public $smarty; + /** + * required by the compiler for BC + * @var string + */ + public $_current_file = null; + /** + * internal flag to enable parser debugging + * @var bool + */ + public $_parserdebug = false; + /**#@-*/ /** - * Class constructor, initializes basic smarty properties - */ + * Initialize new Smarty object + * + */ public function __construct() { - // selfpointer need by some other class methods - $this->smarty = $this; + // selfpointer needed by some other class methods + $this->smarty = $this; if (is_callable('mb_internal_encoding')) { mb_internal_encoding(SMARTY_RESOURCE_CHAR_SET); } @@ -259,241 +552,107 @@ class Smarty extends Smarty_Internal_Data { $this->compile_dir = '.' . DS . 'templates_c' . DS; $this->plugins_dir = array(SMARTY_PLUGINS_DIR); $this->cache_dir = '.' . DS . 'cache' . DS; - $this->config_dir = '.' . DS . 'configs' . DS; - $this->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl'; + $this->config_dir = array('.' . DS . 'configs' . DS); + $this->debug_tpl = 'file:' . dirname(__FILE__) . '/debug.tpl'; if (isset($_SERVER['SCRIPT_NAME'])) { $this->assignGlobal('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']); } } /** - * Class destructor - */ + * Class destructor + */ public function __destruct() { + // intentionally left blank } /** - * fetches a rendered Smarty template - * - * @param string $template the resource handle of the template file or template object - * @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 object $ |null $parent next higher level of Smarty variables - * @return string rendered template output - */ - public function fetch($template, $cache_id = null, $compile_id = null, $parent = null, $display = false) + * <<magic>> set selfpointer on cloned object + */ + public function __clone() { - if (!empty($cache_id) && is_object($cache_id)) { - $parent = $cache_id; - $cache_id = null; - } - if ($parent === null) { - // get default Smarty data object - $parent = $this; - } - // create template object if necessary - ($template instanceof $this->template_class)? $_template = $template : - $_template = $this->createTemplate ($template, $cache_id, $compile_id, $parent, false); - if (isset($this->error_reporting)) { - $_smarty_old_error_level = error_reporting($this->error_reporting); - } - // check URL debugging control - if (!$this->debugging && $this->debugging_ctrl == 'URL') { - if (isset($_SERVER['QUERY_STRING'])) { - $_query_string = $_SERVER['QUERY_STRING']; - } else { - $_query_string = ''; - } - if (false !== strpos($_query_string, $this->smarty_debug_id)) { - if (false !== strpos($_query_string, $this->smarty_debug_id . '=on')) { - // enable debugging for this browser session - setcookie('SMARTY_DEBUG', true); - $this->debugging = true; - } elseif (false !== strpos($_query_string, $this->smarty_debug_id . '=off')) { - // disable debugging for this browser session - setcookie('SMARTY_DEBUG', false); - $this->debugging = false; - } else { - // enable debugging for this page - $this->debugging = true; - } - } else { - if (isset($_COOKIE['SMARTY_DEBUG'])) { - $this->debugging = true; - } - } - } - // obtain data for cache modified check - if ($this->cache_modified_check && $this->caching && $display) { - $_isCached = $_template->isCached() && !$_template->has_nocache_code; - if ($_isCached) { - $_gmt_mtime = gmdate('D, d M Y H:i:s', $_template->getCachedTimestamp()) . ' GMT'; - } else { - $_gmt_mtime = ''; - } - } - // return rendered template - if ((!$this->caching || $_template->resource_object->isEvaluated) && (isset($this->autoload_filters['output']) || isset($this->registered_filters['output']))) { - $_output = Smarty_Internal_Filter_Handler::runFilter('output', $_template->getRenderedTemplate(), $_template); - } else { - $_output = $_template->getRenderedTemplate(); - } - $_template->rendered_content = null; - if (isset($this->error_reporting)) { - error_reporting($_smarty_old_error_level); - } - // display or fetch - if ($display) { - if ($this->caching && $this->cache_modified_check) { - $_last_modified_date = @substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); - if ($_isCached && $_gmt_mtime == $_last_modified_date) { - if (php_sapi_name() == 'cgi') - header('Status: 304 Not Modified'); - else - header('HTTP/1.1 304 Not Modified'); - } else { - header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->getCachedTimestamp()) . ' GMT'); - echo $_output; - } - } else { - echo $_output; - } - // debug output - if ($this->debugging) { - Smarty_Internal_Debug::display_debug($this); - } - return; - } else { - // return fetched content - return $_output; - } + $this->smarty = $this; } - /** - * displays a Smarty template - * - * @param string $ |object $template the resource handle of the template file or template object - * @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 object $parent next higher level of Smarty variables - */ - public function display($template, $cache_id = null, $compile_id = null, $parent = null) - { - // display template - $this->fetch ($template, $cache_id, $compile_id, $parent, true); - } /** - * test if cache i valid - * - * @param string $ |object $template the resource handle of the template file or template object - * @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 object $parent next higher level of Smarty variables - * @return boolean cache status - */ - public function isCached($template, $cache_id = null, $compile_id = null, $parent = null) + * <<magic>> Generic getter. + * + * Calls the appropriate getter function. + * Issues an E_USER_NOTICE if no valid getter is found. + * + * @param string $name property name + * @return mixed + */ + public function __get($name) { - if ($parent === null) { - $parent = $this; - } - if (!($template instanceof $this->template_class)) { - $template = $this->createTemplate ($template, $cache_id, $compile_id, $parent, false); + $allowed = array( + 'template_dir' => 'getTemplateDir', + 'config_dir' => 'getConfigDir', + 'plugins_dir' => 'getPluginsDir', + 'compile_dir' => 'getCompileDir', + 'cache_dir' => 'getCacheDir', + ); + + if (isset($allowed[$name])) { + return $this->{$allowed[$name]}(); + } else { + trigger_error('Undefined property: '. get_class($this) .'::$'. $name, E_USER_NOTICE); } - // return cache status of template - return $template->isCached(); } /** - * creates a data object - * - * @param object $parent next higher level of Smarty variables - * @returns object data object - */ - public function createData($parent = null) + * <<magic>> Generic setter. + * + * Calls the appropriate setter function. + * Issues an E_USER_NOTICE if no valid setter is found. + * + * @param string $name property name + * @param mixed $value parameter passed to setter + */ + public function __set($name, $value) { - return new Smarty_Data($parent, $this); - } + $allowed = array( + 'template_dir' => 'setTemplateDir', + 'config_dir' => 'setConfigDir', + 'plugins_dir' => 'setPluginsDir', + 'compile_dir' => 'setCompileDir', + 'cache_dir' => 'setCacheDir', + ); - /** - * creates a template object - * - * @param string $template the resource handle of the template file - * @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 object $parent next higher level of Smarty variables - * @param boolean $do_clone flag is Smarty object shall be cloned - * @returns object template object - */ - public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true) - { - if (!empty($cache_id) && (is_object($cache_id) || is_array($cache_id))) { - $parent = $cache_id; - $cache_id = null; - } - if (!empty($parent) && is_array($parent)) { - $data = $parent; - $parent = null; - } else { - $data = null; - } - if (!is_object($template)) { - // we got a template resource - // already in template cache? - $_templateId = sha1($template . $cache_id . $compile_id); - if (isset($this->template_objects[$_templateId]) && $this->caching) { - // return cached template object - $tpl = $this->template_objects[$_templateId]; - } else { - // create new template object - if ($do_clone) { - $tpl = new $this->template_class($template, clone $this, $parent, $cache_id, $compile_id); - } else { - $tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id); - } - } + if (isset($allowed[$name])) { + $this->{$allowed[$name]}($value); } else { - // just return a copy of template class - $tpl = $template; - } - // fill data if present - if (!empty($data) && is_array($data)) { - // set up variable values - foreach ($data as $_key => $_val) { - $tpl->tpl_vars[$_key] = new Smarty_variable($_val); - } + trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE); } - return $tpl; } - - /** - * Check if a template resource exists - * - * @param string $resource_name template name - * @return boolean status - */ - function templateExists($resource_name) + * Check if a template resource exists + * + * @param string $resource_name template name + * @return boolean status + */ + public function templateExists($resource_name) { // create template object $save = $this->template_objects; $tpl = new $this->template_class($resource_name, $this); // check if it does exists - $result = $tpl->isExisting(); + $result = $tpl->source->exists; $this->template_objects = $save; return $result; } /** - * Returns a single or all global variables - * - * @param object $smarty - * @param string $varname variable name or null - * @return string variable value or or array of variables - */ - function getGlobal($varname = null) + * Returns a single or all global variables + * + * @param object $smarty + * @param string $varname variable name or null + * @return string variable value or or array of variables + */ + public function getGlobal($varname = null) { if (isset($varname)) { if (isset(self::$global_tpl_vars[$varname])) { @@ -514,168 +673,497 @@ class Smarty extends Smarty_Internal_Data { * Empty cache folder * * @param integer $exp_time expiration time - * @param string $type resource type + * @param string $type resource type * @return integer number of cache files deleted */ function clearAllCache($exp_time = null, $type = null) { - // load cache resource and call clearAll - return $this->loadCacheResource($type)->clearAll($exp_time); + // load cache resource and call clearAll + $_cache_resource = Smarty_CacheResource::load($this, $type); + Smarty_CacheResource::invalidLoadedCache($this); + return $_cache_resource->clearAll($this, $exp_time); } /** * Empty cache for a specific template * - * @param string $template_name template name - * @param string $cache_id cache id - * @param string $compile_id compile id - * @param integer $exp_time expiration time - * @param string $type resource type + * @param string $template_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param integer $exp_time expiration time + * @param string $type resource type * @return integer number of cache files deleted */ - function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null) + public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null) { - // load cache resource and call clear - return $this->loadCacheResource($type)->clear($template_name, $cache_id, $compile_id, $exp_time); + // load cache resource and call clear + $_cache_resource = Smarty_CacheResource::load($this, $type); + Smarty_CacheResource::invalidLoadedCache($this); + return $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time); } /** - * Loads security class and enables security - */ + * Loads security class and enables security + * + * @param string|Smarty_Security $security_class if a string is used, it must be class-name + * @return Smarty current Smarty instance for chaining + * @throws SmartyException when an invalid class name is provided + */ public function enableSecurity($security_class = null) { - if ($security_class instanceof Smarty_Security) { - $this->security_policy = $security_class; - return; - } - if ($security_class == null) { - $security_class = $this->security_class; - } - if (class_exists($security_class)) { - $this->security_policy = new $security_class($this); - } else { + if ($security_class instanceof Smarty_Security) { + $this->security_policy = $security_class; + return $this; + } elseif (is_object($security_class)) { + throw new SmartyException("Class '" . get_class($security_class) . "' must extend Smarty_Security."); + } + if ($security_class == null) { + $security_class = $this->security_class; + } + if (!class_exists($security_class)) { throw new SmartyException("Security class '$security_class' is not defined"); + } elseif ($security_class !== 'Smarty_Security' && !is_subclass_of($security_class, 'Smarty_Security')) { + throw new SmartyException("Class '$security_class' must extend Smarty_Security."); + } else { + $this->security_policy = new $security_class($this); } + + return $this; } /** - * Disable security - */ + * Disable security + * @return Smarty current Smarty instance for chaining + */ public function disableSecurity() { - $this->security_policy = null; + $this->security_policy = null; + + return $this; + } + + /** + * Set template directory + * + * @param string|array $template_dir directory(s) of template sources + * @return Smarty current Smarty instance for chaining + */ + public function setTemplateDir($template_dir) + { + $this->template_dir = array(); + foreach ((array) $template_dir as $k => $v) { + $this->template_dir[$k] = rtrim($v, '/\\') . DS; + } + + return $this; } /** - * Loads cache resource. + * Add template directory(s) * - * @param string $type cache resource type - * @return object of cache resource + * @param string|array $template_dir directory(s) of template sources + * @param string $key of the array element to assign the template dir to + * @return Smarty current Smarty instance for chaining + * @throws SmartyException when the given template directory is not valid */ - public function loadCacheResource($type = null) { - if (!isset($type)) { - $type = $this->caching_type; + public function addTemplateDir($template_dir, $key=null) + { + // make sure we're dealing with an array + $this->template_dir = (array) $this->template_dir; + + if (is_array($template_dir)) { + foreach ($template_dir as $k => $v) { + if (is_int($k)) { + // indexes are not merged but appended + $this->template_dir[] = rtrim($v, '/\\') . DS; + } else { + // string indexes are overridden + $this->template_dir[$k] = rtrim($v, '/\\') . DS; + } + } + } elseif ($key !== null) { + // override directory at specified index + $this->template_dir[$key] = rtrim($template_dir, '/\\') . DS; + } else { + // append new directory + $this->template_dir[] = rtrim($template_dir, '/\\') . DS; } - if (in_array($type, $this->cache_resource_types)) { - $cache_resource_class = 'Smarty_Internal_CacheResource_' . ucfirst($type); - return new $cache_resource_class($this); + + return $this; + } + + /** + * Get template directories + * + * @param mixed index of directory to get, null to get all + * @return array|string list of template directories, or directory of $index + */ + public function getTemplateDir($index=null) + { + if ($index !== null) { + return isset($this->template_dir[$index]) ? $this->template_dir[$index] : null; } - else { - // try plugins dir - $cache_resource_class = 'Smarty_CacheResource_' . ucfirst($type); - if ($this->loadPlugin($cache_resource_class)) { - return new $cache_resource_class($this); + + return $this->template_dir; + } + + /** + * Set config directory + * + * @param string|array $template_dir directory(s) of configuration sources + * @return Smarty current Smarty instance for chaining + */ + public function setConfigDir($config_dir) + { + $this->config_dir = array(); + foreach ((array) $config_dir as $k => $v) { + $this->config_dir[$k] = rtrim($v, '/\\') . DS; + } + + return $this; + } + + /** + * Add config directory(s) + * + * @param string|array $config_dir directory(s) of config sources + * @param string key of the array element to assign the config dir to + * @return Smarty current Smarty instance for chaining + */ + public function addConfigDir($config_dir, $key=null) + { + // make sure we're dealing with an array + $this->config_dir = (array) $this->config_dir; + + if (is_array($config_dir)) { + foreach ($config_dir as $k => $v) { + if (is_int($k)) { + // indexes are not merged but appended + $this->config_dir[] = rtrim($v, '/\\') . DS; + } else { + // string indexes are overridden + $this->config_dir[$k] = rtrim($v, '/\\') . DS; + } } - else { - throw new SmartyException("Unable to load cache resource '{$type}'"); + } elseif( $key !== null ) { + // override directory at specified index + $this->config_dir[$key] = rtrim($config_dir, '/\\') . DS; + } else { + // append new directory + $this->config_dir[] = rtrim($config_dir, '/\\') . DS; + } + + return $this; + } + + /** + * Get config directory + * + * @param mixed index of directory to get, null to get all + * @return array|string configuration directory + */ + public function getConfigDir($index=null) + { + if ($index !== null) { + return isset($this->config_dir[$index]) ? $this->config_dir[$index] : null; + } + + return $this->config_dir; + } + + /** + * Set plugins directory + * + * @param string|array $plugins_dir directory(s) of plugins + * @return Smarty current Smarty instance for chaining + */ + public function setPluginsDir($plugins_dir) + { + $this->plugins_dir = array(); + foreach ((array)$plugins_dir as $k => $v) { + $this->plugins_dir[$k] = rtrim($v, '/\\') . DS; + } + + return $this; + } + + /** + * Adds directory of plugin files + * + * @param object $smarty + * @param string $ |array $ plugins folder + * @return Smarty current Smarty instance for chaining + */ + public function addPluginsDir($plugins_dir) + { + // make sure we're dealing with an array + $this->plugins_dir = (array) $this->plugins_dir; + + if (is_array($plugins_dir)) { + foreach ($plugins_dir as $k => $v) { + if (is_int($k)) { + // indexes are not merged but appended + $this->plugins_dir[] = rtrim($v, '/\\') . DS; + } else { + // string indexes are overridden + $this->plugins_dir[$k] = rtrim($v, '/\\') . DS; + } } + } else { + // append new directory + $this->plugins_dir[] = rtrim($plugins_dir, '/\\') . DS; } + + $this->plugins_dir = array_unique($this->plugins_dir); + return $this; + } + + /** + * Get plugin directories + * + * @return array list of plugin directories + */ + public function getPluginsDir() + { + return $this->plugins_dir; } + /** + * Set compile directory + * + * @param string $compile_dir directory to store compiled templates in + * @return Smarty current Smarty instance for chaining + */ + public function setCompileDir($compile_dir) + { + $this->compile_dir = rtrim($compile_dir, '/\\') . DS; + return $this; + } /** - * Set template directory - * - * @param string $ |array $template_dir folder(s) of template sorces - */ - public function setTemplateDir($template_dir) + * Get compiled directory + * + * @return string path to compiled templates + */ + public function getCompileDir() { - $this->template_dir = (array)$template_dir; - return; + return $this->compile_dir; } /** - * Adds template directory(s) to existing ones - * - * @param string $ |array $template_dir folder(s) of template sources - */ - public function addTemplateDir($template_dir) + * Set cache directory + * + * @param string $cache_dir directory to store cached templates in + * @return Smarty current Smarty instance for chaining + */ + public function setCacheDir($cache_dir) { - $this->template_dir = array_unique(array_merge((array)$this->template_dir, (array)$template_dir)); - return; + $this->cache_dir = rtrim($cache_dir, '/\\') . DS; + return $this; } /** - * Adds directory of plugin files - * - * @param object $smarty - * @param string $ |array $ plugins folder - * @return - */ - function addPluginsDir($plugins_dir) + * Get cache directory + * + * @return string path of cache directory + */ + public function getCacheDir() { - $this->plugins_dir = array_unique(array_merge((array)$this->plugins_dir, (array)$plugins_dir)); - return; + return $this->cache_dir; } + /** + * Set default modifiers + * + * @param array|string $modifiers modifier or list of modifiers to set + * @return Smarty current Smarty instance for chaining + */ + public function setDefaultModifiers($modifiers) + { + $this->default_modifiers = (array) $modifiers; + return $this; + } /** - * return a reference to a registered object - * - * @param string $name object name - * @return object - */ - function getRegisteredObject($name) + * Add default modifiers + * + * @param array|string $modifiers modifier or list of modifiers to add + * @return Smarty current Smarty instance for chaining + */ + public function addDefaultModifiers($modifiers) + { + if (is_array($modifiers)) { + $this->default_modifiers = array_merge($this->default_modifiers, $modifiers); + } else { + $this->default_modifiers[] = $modifiers; + } + + return $this; + } + + /** + * Get default modifiers + * + * @return array list of default modifiers + */ + public function getDefaultModifiers() { - if (!isset($this->registered_objects[$name])) - throw new SmartyException("'$name' is not a registered object"); + return $this->default_modifiers; + } - if (!is_object($this->registered_objects[$name][0])) - throw new SmartyException("registered '$name' is not an object"); - return $this->registered_objects[$name][0]; + /** + * Set autoload filters + * + * @param array $filters filters to load automatically + * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types + * @return Smarty current Smarty instance for chaining + */ + public function setAutoloadFilters($filters, $type=null) + { + if ($type !== null) { + $this->autoload_filters[$type] = (array) $filters; + } else { + $this->autoload_filters = (array) $filters; + } + + return $this; } + /** + * Add autoload filters + * + * @param array $filters filters to load automatically + * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types + * @return Smarty current Smarty instance for chaining + */ + public function addAutoloadFilters($filters, $type=null) + { + if ($type !== null) { + if (!empty($this->autoload_filters[$type])) { + $this->autoload_filters[$type] = array_merge($this->autoload_filters[$type], (array) $filters); + } else { + $this->autoload_filters[$type] = (array) $filters; + } + } else { + foreach ((array) $filters as $key => $value) { + if (!empty($this->autoload_filters[$key])) { + $this->autoload_filters[$key] = array_merge($this->autoload_filters[$key], (array) $value); + } else { + $this->autoload_filters[$key] = (array) $value; + } + } + } + + return $this; + } /** - * return name of debugging template - * - * @return string - */ - function getDebugTemplate() + * Get autoload filters + * + * @param string $type type of filter to get autoloads for. Defaults to all autoload filters + * @return array array( 'type1' => array( 'filter1', 'filter2', … ) ) or array( 'filter1', 'filter2', …) if $type was specified + */ + public function getAutoloadFilters($type=null) + { + if ($type !== null) { + return isset($this->autoload_filters[$type]) ? $this->autoload_filters[$type] : array(); + } + + return $this->autoload_filters; + } + + /** + * return name of debugging template + * + * @return string + */ + public function getDebugTemplate() { return $this->debug_tpl; } /** - * set the debug template - * - * @param string $tpl_name - * @return bool - */ - function setDebugTemplate($tpl_name) + * set the debug template + * + * @param string $tpl_name + * @return Smarty current Smarty instance for chaining + * @throws SmartyException if file is not readable + */ + public function setDebugTemplate($tpl_name) { - return $this->debug_tpl = $tpl_name; + if (!is_readable($tpl_name)) { + throw new SmartyException("Unknown file '{$tpl_name}'"); + } + $this->debug_tpl = $tpl_name; + + return $this; } /** - * Takes unknown classes and loads plugin files for them - * class name format: Smarty_PluginType_PluginName - * plugin filename format: plugintype.pluginname.php - * - * @param string $plugin_name class plugin name to load - * @return string |boolean filepath of loaded file or false - */ + * creates a template object + * + * @param string $template the resource handle of the template file + * @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 object $parent next higher level of Smarty variables + * @param boolean $do_clone flag is Smarty object shall be cloned + * @return object template object + */ + public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true) + { + if (!empty($cache_id) && (is_object($cache_id) || is_array($cache_id))) { + $parent = $cache_id; + $cache_id = null; + } + if (!empty($parent) && is_array($parent)) { + $data = $parent; + $parent = null; + } else { + $data = null; + } + // default to cache_id and compile_id of Smarty object + $cache_id = $cache_id === null ? $this->cache_id : $cache_id; + $compile_id = $compile_id === null ? $this->compile_id : $compile_id; + // already in template cache? + $_templateId = sha1($template . $cache_id . $compile_id); + if ($do_clone) { + if (isset($this->template_objects[$_templateId])) { + // return cached template object + $tpl = clone $this->template_objects[$_templateId]; + $tpl->smarty = clone $tpl->smarty; + $tpl->parent = $parent; + } else { + $tpl = new $this->template_class($template, clone $this, $parent, $cache_id, $compile_id); + } + } else { + if (isset($this->template_objects[$_templateId])) { + // return cached template object + $tpl = $this->template_objects[$_templateId]; + } else { + $tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id); + } + } + // fill data if present + if (!empty($data) && is_array($data)) { + // set up variable values + foreach ($data as $_key => $_val) { + $tpl->tpl_vars[$_key] = new Smarty_variable($_val); + } + } + return $tpl; + } + + + /** + * Takes unknown classes and loads plugin files for them + * class name format: Smarty_PluginType_PluginName + * plugin filename format: plugintype.pluginname.php + * + * @param string $plugin_name class plugin name to load + * @param bool $check check if already loaded + * @return string |boolean filepath of loaded file or false + */ public function loadPlugin($plugin_name, $check = true) { // if function or class exists, exit silently (already loaded) @@ -702,21 +1190,67 @@ class Smarty extends Smarty_Internal_Data { // plugin filename is expected to be: [type].[name].php $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php"; // loop through plugin dirs and find the plugin - foreach((array)$this->plugins_dir as $_plugin_dir) { - if (strpos('/\\', substr($_plugin_dir, -1)) === false) { - $_plugin_dir .= DS; - } + foreach($this->getPluginsDir() as $_plugin_dir) { $file = $_plugin_dir . $_plugin_filename; if (file_exists($file)) { require_once($file); return $file; } + if ($this->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) { + // try PHP include_path + if (($file = Smarty_Internal_Get_Include_Path::getIncludePath($file)) !== false) { + require_once($file); + return $file; + } + } } // no plugin loaded return false; } /** + * Compile all template files + * + * @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 + */ + public function compileAllTemplates($extention = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null) + { + return Smarty_Internal_Utility::compileAllTemplates($extention, $force_compile, $time_limit, $max_errors, $this); + } + + /** + * Compile all config files + * + * @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 + */ + public function compileAllConfig($extention = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null) + { + return Smarty_Internal_Utility::compileAllConfig($extention, $force_compile, $time_limit, $max_errors, $this); + } + + /** + * Delete compiled template file + * + * @param string $resource_name template name + * @param string $compile_id compile id + * @param integer $exp_time expiration time + * @return integer number of template files deleted + */ + public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null) + { + return Smarty_Internal_Utility::clearCompiledTemplate($resource_name, $compile_id, $exp_time, $this); + } + + + /** * Return array of tag/attributes of all tags used by an template * * @param object $templae template object @@ -728,101 +1262,53 @@ class Smarty extends Smarty_Internal_Data { } /** - * clean up properties on cloned object + * Run installation test + * + * @param array $errors Array to write errors into, rather than outputting them + * @return boolean true if setup is fine, false if something is wrong */ - public function __clone() + public function testInstall(&$errors=null) { - // clear config vars - $this->config_vars = array(); - // clear assigned tpl vars - $this->tpl_vars = array(); - // clear objects for external methods - unset($this->Register); - unset($this->Filter); - } - + return Smarty_Internal_Utility::testInstall($this, $errors); + } - /** - * Handle unknown class methods - * - * @param string $name unknown methode name - * @param array $args aurgument array - */ - public function __call($name, $args) - { - static $camel_func; - if (!isset($camel_func)) - $camel_func = create_function('$c', 'return "_" . strtolower($c[1]);'); - // see if this is a set/get for a property - $first3 = strtolower(substr($name, 0, 3)); - if (in_array($first3, array('set', 'get')) && substr($name, 3, 1) !== '_') { - // try to keep case correct for future PHP 6.0 case-sensitive class methods - // lcfirst() not available < PHP 5.3.0, so improvise - $property_name = strtolower(substr($name, 3, 1)) . substr($name, 4); - // convert camel case to underscored name - $property_name = preg_replace_callback('/([A-Z])/', $camel_func, $property_name); - if (!property_exists($this, $property_name)) { - throw new SmartyException("property '$property_name' does not exist."); - return false; - } - if ($first3 == 'get') - return $this->$property_name; - else - return $this->$property_name = $args[0]; - } - // Smarty Backward Compatible wrapper - if (strpos($name,'_') !== false) { - if (!isset($this->wrapper)) { - $this->wrapper = new Smarty_Internal_Wrapper($this); - } - return $this->wrapper->convert($name, $args); - } - // external Smarty methods ? - foreach(array('Filter','Register') as $external) { - if (class_exists("Smarty_Internal_{$external}") && method_exists("Smarty_Internal_{$external}",$name)) { - if (!isset($this->$external)) { - $class = "Smarty_Internal_{$external}"; - $this->$external = new $class($this); - } - return call_user_func_array(array($this->$external,$name), $args); - } - } - if (in_array($name,array('clearCompiledTemplate','compileAllTemplates','compileAllConfig','testInstall','getTags'))) { - if (!isset($this->utility)) { - $this->utility = new Smarty_Internal_Utility($this); - } - return call_user_func_array(array($this->utility,$name), $args); - } - // PHP4 call to constructor? - if (strtolower($name) == 'smarty') { - throw new SmartyException('Please use parent::__construct() to call parent constuctor'); - return false; - } - throw new SmartyException("Call of unknown function '$name'."); - } } /** - * Autoloader - */ -function smartyAutoload($class) -{ - $_class = strtolower($class); - if (substr($_class, 0, 16) === 'smarty_internal_' || $_class == 'smarty_security') { - include SMARTY_SYSPLUGINS_DIR . $_class . '.php'; - } +* Smarty exception class +* @package Smarty +*/ +class SmartyException extends Exception { } /** - * Smarty exception class - */ -Class SmartyException extends Exception { +* Smarty compiler exception class +* @package Smarty +*/ +class SmartyCompilerException extends SmartyException { } /** - * Smarty compiler exception class - */ -Class SmartyCompilerException extends SmartyException { +* Autoloader +*/ +function smartyAutoload($class) +{ + $_class = strtolower($class); + if (substr($_class, 0, 16) == 'smarty_internal_' + || in_array( $_class, array( + 'smarty_config_source', + 'smarty_config_compiled', + 'smarty_security', + 'smarty_cacheresource', + 'smarty_cacheresource_custom', + 'smarty_cacheresource_keyvaluestore', + 'smarty_resource', + 'smarty_resource_custom', + 'smarty_resource_uncompiled', + 'smarty_resource_recompiled', + ))) { + include SMARTY_SYSPLUGINS_DIR . $_class . '.php'; + } } -?> +?>
\ No newline at end of file |
