3 * Project: Smarty: the PHP compiling template engine
4 * File: Smarty.class.php
5 * SVN: $Id: Smarty.class.php 4848 2014-06-08 18:12:09Z Uwe.Tews@googlemail.com $
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * For questions, help, comments, discussion, etc., please join the
18 * Smarty mailing list. Send a blank e-mail to
19 * smarty-discussion-subscribe@googlegroups.com
21 * @link http://www.smarty.net/
22 * @copyright 2008 New Digital Group, Inc.
23 * @author Monte Ohrt <monte at ohrt dot com>
31 * define shorthand directory separator constant
34 define('DS', DIRECTORY_SEPARATOR
);
38 * set SMARTY_DIR to absolute path to Smarty library files.
39 * Sets SMARTY_DIR only if user application has not already defined it.
41 if (!defined('SMARTY_DIR')) {
42 define('SMARTY_DIR', dirname(__FILE__
) . DS
);
46 * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins.
47 * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it.
49 if (!defined('SMARTY_SYSPLUGINS_DIR')) {
50 define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR
. 'sysplugins' . DS
);
52 if (!defined('SMARTY_PLUGINS_DIR')) {
53 define('SMARTY_PLUGINS_DIR', SMARTY_DIR
. 'plugins' . DS
);
55 if (!defined('SMARTY_MBSTRING')) {
56 define('SMARTY_MBSTRING', function_exists('mb_split'));
58 if (!defined('SMARTY_RESOURCE_CHAR_SET')) {
59 // UTF-8 can only be done properly when mbstring is available!
61 * @deprecated in favor of Smarty::$_CHARSET
63 define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ?
'UTF-8' : 'ISO-8859-1');
65 if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) {
67 * @deprecated in favor of Smarty::$_DATE_FORMAT
69 define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y');
73 * register the class autoloader
75 if (!defined('SMARTY_SPL_AUTOLOAD')) {
76 define('SMARTY_SPL_AUTOLOAD', 0);
79 if (SMARTY_SPL_AUTOLOAD
&& set_include_path(get_include_path() . PATH_SEPARATOR
. SMARTY_SYSPLUGINS_DIR
) !== false) {
80 $registeredAutoLoadFunctions = spl_autoload_functions();
81 if (!isset($registeredAutoLoadFunctions['spl_autoload'])) {
82 spl_autoload_register();
85 spl_autoload_register('smartyAutoload');
89 * Load always needed external class files
91 include_once SMARTY_SYSPLUGINS_DIR
. 'smarty_internal_data.php';
92 include_once SMARTY_SYSPLUGINS_DIR
. 'smarty_internal_templatebase.php';
93 include_once SMARTY_SYSPLUGINS_DIR
. 'smarty_internal_template.php';
94 include_once SMARTY_SYSPLUGINS_DIR
. 'smarty_resource.php';
95 include_once SMARTY_SYSPLUGINS_DIR
. 'smarty_internal_resource_file.php';
96 include_once SMARTY_SYSPLUGINS_DIR
. 'smarty_cacheresource.php';
97 include_once SMARTY_SYSPLUGINS_DIR
. 'smarty_internal_cacheresource_file.php';
100 * This is the main Smarty class
104 class Smarty
extends Smarty_Internal_TemplateBase
107 * constant definitions
113 const SMARTY_VERSION
= 'Smarty-3.1.19';
116 * define variable scopes
118 const SCOPE_LOCAL
= 0;
119 const SCOPE_PARENT
= 1;
120 const SCOPE_ROOT
= 2;
121 const SCOPE_GLOBAL
= 3;
123 * define caching modes
125 const CACHING_OFF
= 0;
126 const CACHING_LIFETIME_CURRENT
= 1;
127 const CACHING_LIFETIME_SAVED
= 2;
129 * define constant for clearing cache files be saved expiration datees
131 const CLEAR_EXPIRED
= - 1;
134 * define compile check modes
136 const COMPILECHECK_OFF
= 0;
137 const COMPILECHECK_ON
= 1;
138 const COMPILECHECK_CACHEMISS
= 2;
140 * modes for handling of "<?php ... ?>" tags in templates.
142 const PHP_PASSTHRU
= 0; //-> print tags as plain text
143 const PHP_QUOTE
= 1; //-> escape tags as entities
144 const PHP_REMOVE
= 2; //-> escape tags as entities
145 const PHP_ALLOW
= 3; //-> escape tags as entities
149 const FILTER_POST
= 'post';
150 const FILTER_PRE
= 'pre';
151 const FILTER_OUTPUT
= 'output';
152 const FILTER_VARIABLE
= 'variable';
156 const PLUGIN_FUNCTION
= 'function';
157 const PLUGIN_BLOCK
= 'block';
158 const PLUGIN_COMPILER
= 'compiler';
159 const PLUGIN_MODIFIER
= 'modifier';
160 const PLUGIN_MODIFIERCOMPILER
= 'modifiercompiler';
165 * assigned global tpl vars
167 public static $global_tpl_vars = array();
170 * error handler returned by set_error_hanlder() in Smarty::muteExpectedErrors()
172 public static $_previous_error_handler = null;
174 * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors()
176 public static $_muted_directories = array();
178 * Flag denoting if Multibyte String functions are available
180 public static $_MBSTRING = SMARTY_MBSTRING
;
182 * The character set to adhere to (e.g. "UTF-8")
184 public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET
;
186 * The date format to be used internally
187 * (accepts date() and strftime())
189 public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT
;
191 * Flag denoting if PCRE should run in UTF-8 mode
193 public static $_UTF8_MODIFIER = 'u';
196 * Flag denoting if operating system is windows
198 public static $_IS_WINDOWS = false;
205 * auto literal on delimiters with whitspace
209 public $auto_literal = true;
211 * display error on not assigned variables
215 public $error_unassigned = false;
217 * look up relative filepaths in include_path
221 public $use_include_path = false;
227 private $template_dir = array();
229 * joined template directory string used in cache keys
233 public $joined_template_dir = null;
235 * joined config directory string used in cache keys
239 public $joined_config_dir = null;
241 * default template handler
245 public $default_template_handler_func = null;
247 * default config handler
251 public $default_config_handler_func = null;
253 * default plugin handler
257 public $default_plugin_handler_func = null;
263 private $compile_dir = null;
269 private $plugins_dir = array();
275 private $cache_dir = null;
281 private $config_dir = array();
283 * force template compiling?
287 public $force_compile = false;
289 * check template for modifications?
293 public $compile_check = true;
295 * use sub dirs for compiled/cached files?
299 public $use_sub_dirs = false;
301 * allow ambiguous resources (that are made unique by the resource handler)
305 public $allow_ambiguous_resources = false;
311 public $caching = false;
313 * merge compiled includes
317 public $merge_compiled_includes = false;
319 * template inheritance merge compiled includes
323 public $inheritance_merge_compiled_includes = true;
325 * cache lifetime in seconds
329 public $cache_lifetime = 3600;
331 * force cache file creation
335 public $force_cache = false;
337 * Set this if you want different sets of cache files for the same
342 public $cache_id = null;
344 * Set this if you want different sets of compiled files for the same
349 public $compile_id = null;
351 * template left-delimiter
355 public $left_delimiter = "{";
357 * template right-delimiter
361 public $right_delimiter = "}";
367 * This should be instance of Smarty_Security.
370 * @see Smarty_Security
372 public $security_class = 'Smarty_Security';
374 * implementation of security class
376 * @var Smarty_Security
378 public $security_policy = null;
380 * controls handling of PHP-blocks
384 public $php_handling = self
::PHP_PASSTHRU
;
386 * controls if the php template file resource is allowed
390 public $allow_php_templates = false;
392 * Should compiled-templates be prevented from being called directly?
394 * Currently used by Smarty_Internal_Template only.
399 public $direct_access_security = true;
403 * Setting this to true enables the debug-console.
407 public $debugging = false;
409 * This determines if debugging is enable-able from the browser.
411 * <li>NONE => no debugging control allowed</li>
412 * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
417 public $debugging_ctrl = 'NONE';
419 * Name of debugging URL-param.
420 * Only used when $debugging_ctrl is set to 'URL'.
421 * The name of the URL-parameter that activates debugging.
425 public $smarty_debug_id = 'SMARTY_DEBUG';
427 * Path of debug template.
431 public $debug_tpl = null;
433 * When set, smarty uses this value as error_reporting-level.
437 public $error_reporting = null;
439 * Internal flag for getTags()
443 public $get_used_tags = false;
446 * config var settings
450 * Controls whether variables with the same name overwrite each other.
454 public $config_overwrite = true;
456 * Controls whether config values of on/true/yes and off/false/no get converted to boolean.
460 public $config_booleanize = true;
462 * Controls whether hidden config sections/vars are read from the file.
466 public $config_read_hidden = false;
475 * locking concurrent compiles
479 public $compile_locking = true;
481 * Controls whether cache resources should emply locking mechanism
485 public $cache_locking = false;
487 * seconds to wait for acquiring a lock before ignoring the write lock
491 public $locking_timeout = 10;
496 * global template functions
500 public $template_functions = array();
502 * resource type used if none given
503 * Must be an valid key of $registered_resources.
507 public $default_resource_type = 'file';
510 * Must be an element of $cache_resource_types.
514 public $caching_type = 'file';
516 * internal config properties
520 public $properties = array();
526 public $default_config_type = 'file';
528 * cached template objects
532 public $template_objects = array();
534 * check If-Modified-Since headers
538 public $cache_modified_check = false;
544 public $registered_plugins = array();
546 * plugin search order
550 public $plugin_search_order = array('function', 'block', 'compiler', 'class');
556 public $registered_objects = array();
562 public $registered_classes = array();
568 public $registered_filters = array();
570 * registered resources
574 public $registered_resources = array();
576 * resource handler cache
580 public $_resource_handlers = array();
582 * registered cache resources
586 public $registered_cache_resources = array();
588 * cache resource handler cache
592 public $_cacheresource_handlers = array();
598 public $autoload_filters = array();
604 public $default_modifiers = array();
606 * autoescape variable output
610 public $escape_html = false;
612 * global internal smarty vars
616 public static $_smarty_vars = array();
618 * start time for execution time calculation
622 public $start_time = 0;
624 * default file permissions
628 public $_file_perms = 0644;
630 * default dir permissions
634 public $_dir_perms = 0771;
636 * block tag hierarchy
640 public $_tag_stack = array();
642 * self pointer to Smarty object
648 * required by the compiler for BC
652 public $_current_file = null;
654 * internal flag to enable parser debugging
658 public $_parserdebug = false;
660 * Saved parameter of merged templates during compilation
664 public $merged_templates_func = array();
668 * Initialize new Smarty object
671 public function __construct()
673 // selfpointer needed by some other class methods
674 $this->smarty
= $this;
675 if (is_callable('mb_internal_encoding')) {
676 mb_internal_encoding(Smarty
::$_CHARSET);
678 $this->start_time
= microtime(true);
680 $this->setTemplateDir('.' . DS
. 'templates' . DS
)
681 ->setCompileDir('.' . DS
. 'templates_c' . DS
)
682 ->setPluginsDir(SMARTY_PLUGINS_DIR
)
683 ->setCacheDir('.' . DS
. 'cache' . DS
)
684 ->setConfigDir('.' . DS
. 'configs' . DS
);
686 $this->debug_tpl
= 'file:' . dirname(__FILE__
) . '/debug.tpl';
687 if (isset($_SERVER['SCRIPT_NAME'])) {
688 $this->assignGlobal('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']);
695 public function __destruct()
697 // intentionally left blank
701 * <<magic>> set selfpointer on cloned object
703 public function __clone()
705 $this->smarty
= $this;
709 * <<magic>> Generic getter.
710 * Calls the appropriate getter function.
711 * Issues an E_USER_NOTICE if no valid getter is found.
713 * @param string $name property name
717 public function __get($name)
720 'template_dir' => 'getTemplateDir',
721 'config_dir' => 'getConfigDir',
722 'plugins_dir' => 'getPluginsDir',
723 'compile_dir' => 'getCompileDir',
724 'cache_dir' => 'getCacheDir',
727 if (isset($allowed[$name])) {
728 return $this->{$allowed[$name]}();
730 trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE
);
735 * <<magic>> Generic setter.
736 * Calls the appropriate setter function.
737 * Issues an E_USER_NOTICE if no valid setter is found.
739 * @param string $name property name
740 * @param mixed $value parameter passed to setter
742 public function __set($name, $value)
745 'template_dir' => 'setTemplateDir',
746 'config_dir' => 'setConfigDir',
747 'plugins_dir' => 'setPluginsDir',
748 'compile_dir' => 'setCompileDir',
749 'cache_dir' => 'setCacheDir',
752 if (isset($allowed[$name])) {
753 $this->{$allowed[$name]}($value);
755 trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE
);
760 * Check if a template resource exists
762 * @param string $resource_name template name
764 * @return boolean status
766 public function templateExists($resource_name)
768 // create template object
769 $save = $this->template_objects
;
770 $tpl = new $this->template_class($resource_name, $this);
771 // check if it does exists
772 $result = $tpl->source
->exists
;
773 $this->template_objects
= $save;
779 * Returns a single or all global variables
781 * @param string $varname variable name or null
783 * @return string variable value or or array of variables
785 public function getGlobal($varname = null)
787 if (isset($varname)) {
788 if (isset(self
::$global_tpl_vars[$varname])) {
789 return self
::$global_tpl_vars[$varname]->value
;
795 foreach (self
::$global_tpl_vars AS $key => $var) {
796 $_result[$key] = $var->value
;
806 * @param integer $exp_time expiration time
807 * @param string $type resource type
809 * @return integer number of cache files deleted
811 public function clearAllCache($exp_time = null, $type = null)
813 // load cache resource and call clearAll
814 $_cache_resource = Smarty_CacheResource
::load($this, $type);
815 Smarty_CacheResource
::invalidLoadedCache($this);
817 return $_cache_resource->clearAll($this, $exp_time);
821 * Empty cache for a specific template
823 * @param string $template_name template name
824 * @param string $cache_id cache id
825 * @param string $compile_id compile id
826 * @param integer $exp_time expiration time
827 * @param string $type resource type
829 * @return integer number of cache files deleted
831 public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
833 // load cache resource and call clear
834 $_cache_resource = Smarty_CacheResource
::load($this, $type);
835 Smarty_CacheResource
::invalidLoadedCache($this);
837 return $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time);
841 * Loads security class and enables security
843 * @param string|Smarty_Security $security_class if a string is used, it must be class-name
845 * @return Smarty current Smarty instance for chaining
846 * @throws SmartyException when an invalid class name is provided
848 public function enableSecurity($security_class = null)
850 if ($security_class instanceof Smarty_Security
) {
851 $this->security_policy
= $security_class;
854 } elseif (is_object($security_class)) {
855 throw new SmartyException("Class '" . get_class($security_class) . "' must extend Smarty_Security.");
857 if ($security_class == null) {
858 $security_class = $this->security_class
;
860 if (!class_exists($security_class)) {
861 throw new SmartyException("Security class '$security_class' is not defined");
862 } elseif ($security_class !== 'Smarty_Security' && !is_subclass_of($security_class, 'Smarty_Security')) {
863 throw new SmartyException("Class '$security_class' must extend Smarty_Security.");
865 $this->security_policy
= new $security_class($this);
874 * @return Smarty current Smarty instance for chaining
876 public function disableSecurity()
878 $this->security_policy
= null;
884 * Set template directory
886 * @param string|array $template_dir directory(s) of template sources
888 * @return Smarty current Smarty instance for chaining
890 public function setTemplateDir($template_dir)
892 $this->template_dir
= array();
893 foreach ((array) $template_dir as $k => $v) {
894 $this->template_dir
[$k] = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS
;
897 $this->joined_template_dir
= join(DIRECTORY_SEPARATOR
, $this->template_dir
);
903 * Add template directory(s)
905 * @param string|array $template_dir directory(s) of template sources
906 * @param string $key of the array element to assign the template dir to
908 * @return Smarty current Smarty instance for chaining
909 * @throws SmartyException when the given template directory is not valid
911 public function addTemplateDir($template_dir, $key = null)
913 // make sure we're dealing with an array
914 $this->template_dir
= (array) $this->template_dir
;
916 if (is_array($template_dir)) {
917 foreach ($template_dir as $k => $v) {
918 $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS
;
920 // indexes are not merged but appended
921 $this->template_dir
[] = $v;
923 // string indexes are overridden
924 $this->template_dir
[$k] = $v;
928 $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($template_dir, '/\\')) . DS
;
930 // override directory at specified index
931 $this->template_dir
[$key] = $v;
933 // append new directory
934 $this->template_dir
[] = $v;
937 $this->joined_template_dir
= join(DIRECTORY_SEPARATOR
, $this->template_dir
);
943 * Get template directories
945 * @param mixed $index index of directory to get, null to get all
947 * @return array|string list of template directories, or directory of $index
949 public function getTemplateDir($index = null)
951 if ($index !== null) {
952 return isset($this->template_dir
[$index]) ?
$this->template_dir
[$index] : null;
955 return (array) $this->template_dir
;
959 * Set config directory
963 * @return Smarty current Smarty instance for chaining
965 public function setConfigDir($config_dir)
967 $this->config_dir
= array();
968 foreach ((array) $config_dir as $k => $v) {
969 $this->config_dir
[$k] = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS
;
972 $this->joined_config_dir
= join(DIRECTORY_SEPARATOR
, $this->config_dir
);
978 * Add config directory(s)
980 * @param string|array $config_dir directory(s) of config sources
981 * @param mixed $key key of the array element to assign the config dir to
983 * @return Smarty current Smarty instance for chaining
985 public function addConfigDir($config_dir, $key = null)
987 // make sure we're dealing with an array
988 $this->config_dir
= (array) $this->config_dir
;
990 if (is_array($config_dir)) {
991 foreach ($config_dir as $k => $v) {
992 $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS
;
994 // indexes are not merged but appended
995 $this->config_dir
[] = $v;
997 // string indexes are overridden
998 $this->config_dir
[$k] = $v;
1002 $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($config_dir, '/\\')) . DS
;
1003 if ($key !== null) {
1004 // override directory at specified index
1005 $this->config_dir
[$key] = rtrim($v, '/\\') . DS
;
1007 // append new directory
1008 $this->config_dir
[] = rtrim($v, '/\\') . DS
;
1012 $this->joined_config_dir
= join(DIRECTORY_SEPARATOR
, $this->config_dir
);
1018 * Get config directory
1020 * @param mixed $index index of directory to get, null to get all
1022 * @return array|string configuration directory
1024 public function getConfigDir($index = null)
1026 if ($index !== null) {
1027 return isset($this->config_dir
[$index]) ?
$this->config_dir
[$index] : null;
1030 return (array) $this->config_dir
;
1034 * Set plugins directory
1036 * @param string|array $plugins_dir directory(s) of plugins
1038 * @return Smarty current Smarty instance for chaining
1040 public function setPluginsDir($plugins_dir)
1042 $this->plugins_dir
= array();
1043 foreach ((array) $plugins_dir as $k => $v) {
1044 $this->plugins_dir
[$k] = rtrim($v, '/\\') . DS
;
1051 * Adds directory of plugin files
1053 * @param $plugins_dir
1055 * @return Smarty current Smarty instance for chaining
1057 public function addPluginsDir($plugins_dir)
1059 // make sure we're dealing with an array
1060 $this->plugins_dir
= (array) $this->plugins_dir
;
1062 if (is_array($plugins_dir)) {
1063 foreach ($plugins_dir as $k => $v) {
1065 // indexes are not merged but appended
1066 $this->plugins_dir
[] = rtrim($v, '/\\') . DS
;
1068 // string indexes are overridden
1069 $this->plugins_dir
[$k] = rtrim($v, '/\\') . DS
;
1073 // append new directory
1074 $this->plugins_dir
[] = rtrim($plugins_dir, '/\\') . DS
;
1077 $this->plugins_dir
= array_unique($this->plugins_dir
);
1083 * Get plugin directories
1085 * @return array list of plugin directories
1087 public function getPluginsDir()
1089 return (array) $this->plugins_dir
;
1093 * Set compile directory
1095 * @param string $compile_dir directory to store compiled templates in
1097 * @return Smarty current Smarty instance for chaining
1099 public function setCompileDir($compile_dir)
1101 $this->compile_dir
= rtrim($compile_dir, '/\\') . DS
;
1102 if (!isset(Smarty
::$_muted_directories[$this->compile_dir
])) {
1103 Smarty
::$_muted_directories[$this->compile_dir
] = null;
1110 * Get compiled directory
1112 * @return string path to compiled templates
1114 public function getCompileDir()
1116 return $this->compile_dir
;
1120 * Set cache directory
1122 * @param string $cache_dir directory to store cached templates in
1124 * @return Smarty current Smarty instance for chaining
1126 public function setCacheDir($cache_dir)
1128 $this->cache_dir
= rtrim($cache_dir, '/\\') . DS
;
1129 if (!isset(Smarty
::$_muted_directories[$this->cache_dir
])) {
1130 Smarty
::$_muted_directories[$this->cache_dir
] = null;
1137 * Get cache directory
1139 * @return string path of cache directory
1141 public function getCacheDir()
1143 return $this->cache_dir
;
1147 * Set default modifiers
1149 * @param array|string $modifiers modifier or list of modifiers to set
1151 * @return Smarty current Smarty instance for chaining
1153 public function setDefaultModifiers($modifiers)
1155 $this->default_modifiers
= (array) $modifiers;
1161 * Add default modifiers
1163 * @param array|string $modifiers modifier or list of modifiers to add
1165 * @return Smarty current Smarty instance for chaining
1167 public function addDefaultModifiers($modifiers)
1169 if (is_array($modifiers)) {
1170 $this->default_modifiers
= array_merge($this->default_modifiers
, $modifiers);
1172 $this->default_modifiers
[] = $modifiers;
1179 * Get default modifiers
1181 * @return array list of default modifiers
1183 public function getDefaultModifiers()
1185 return $this->default_modifiers
;
1189 * Set autoload filters
1191 * @param array $filters filters to load automatically
1192 * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types
1194 * @return Smarty current Smarty instance for chaining
1196 public function setAutoloadFilters($filters, $type = null)
1198 if ($type !== null) {
1199 $this->autoload_filters
[$type] = (array) $filters;
1201 $this->autoload_filters
= (array) $filters;
1208 * Add autoload filters
1210 * @param array $filters filters to load automatically
1211 * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types
1213 * @return Smarty current Smarty instance for chaining
1215 public function addAutoloadFilters($filters, $type = null)
1217 if ($type !== null) {
1218 if (!empty($this->autoload_filters
[$type])) {
1219 $this->autoload_filters
[$type] = array_merge($this->autoload_filters
[$type], (array) $filters);
1221 $this->autoload_filters
[$type] = (array) $filters;
1224 foreach ((array) $filters as $key => $value) {
1225 if (!empty($this->autoload_filters
[$key])) {
1226 $this->autoload_filters
[$key] = array_merge($this->autoload_filters
[$key], (array) $value);
1228 $this->autoload_filters
[$key] = (array) $value;
1237 * Get autoload filters
1239 * @param string $type type of filter to get autoloads for. Defaults to all autoload filters
1241 * @return array array( 'type1' => array( 'filter1', 'filter2', … ) ) or array( 'filter1', 'filter2', …) if $type was specified
1243 public function getAutoloadFilters($type = null)
1245 if ($type !== null) {
1246 return isset($this->autoload_filters
[$type]) ?
$this->autoload_filters
[$type] : array();
1249 return $this->autoload_filters
;
1253 * return name of debugging template
1257 public function getDebugTemplate()
1259 return $this->debug_tpl
;
1263 * set the debug template
1265 * @param string $tpl_name
1267 * @return Smarty current Smarty instance for chaining
1268 * @throws SmartyException if file is not readable
1270 public function setDebugTemplate($tpl_name)
1272 if (!is_readable($tpl_name)) {
1273 throw new SmartyException("Unknown file '{$tpl_name}'");
1275 $this->debug_tpl
= $tpl_name;
1281 * creates a template object
1283 * @param string $template the resource handle of the template file
1284 * @param mixed $cache_id cache id to be used with this template
1285 * @param mixed $compile_id compile id to be used with this template
1286 * @param object $parent next higher level of Smarty variables
1287 * @param boolean $do_clone flag is Smarty object shall be cloned
1289 * @return object template object
1291 public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true)
1293 if ($cache_id !== null && (is_object($cache_id) ||
is_array($cache_id))) {
1294 $parent = $cache_id;
1297 if ($parent !== null && is_array($parent)) {
1303 // default to cache_id and compile_id of Smarty object
1304 $cache_id = $cache_id === null ?
$this->cache_id
: $cache_id;
1305 $compile_id = $compile_id === null ?
$this->compile_id
: $compile_id;
1306 // already in template cache?
1307 if ($this->allow_ambiguous_resources
) {
1308 $_templateId = Smarty_Resource
::getUniqueTemplateName($this, $template) . $cache_id . $compile_id;
1310 $_templateId = $this->joined_template_dir
. '#' . $template . $cache_id . $compile_id;
1312 if (isset($_templateId[150])) {
1313 $_templateId = sha1($_templateId);
1316 if (isset($this->template_objects
[$_templateId])) {
1317 // return cached template object
1318 $tpl = clone $this->template_objects
[$_templateId];
1319 $tpl->smarty
= clone $tpl->smarty
;
1320 $tpl->parent
= $parent;
1321 $tpl->tpl_vars
= array();
1322 $tpl->config_vars
= array();
1324 $tpl = new $this->template_class($template, clone $this, $parent, $cache_id, $compile_id);
1327 if (isset($this->template_objects
[$_templateId])) {
1328 // return cached template object
1329 $tpl = $this->template_objects
[$_templateId];
1330 $tpl->parent
= $parent;
1331 $tpl->tpl_vars
= array();
1332 $tpl->config_vars
= array();
1334 $tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id);
1337 // fill data if present
1338 if (!empty($data) && is_array($data)) {
1339 // set up variable values
1340 foreach ($data as $_key => $_val) {
1341 $tpl->tpl_vars
[$_key] = new Smarty_variable($_val);
1349 * Takes unknown classes and loads plugin files for them
1350 * class name format: Smarty_PluginType_PluginName
1351 * plugin filename format: plugintype.pluginname.php
1353 * @param string $plugin_name class plugin name to load
1354 * @param bool $check check if already loaded
1356 * @throws SmartyException
1357 * @return string |boolean filepath of loaded file or false
1359 public function loadPlugin($plugin_name, $check = true)
1361 // if function or class exists, exit silently (already loaded)
1362 if ($check && (is_callable($plugin_name) ||
class_exists($plugin_name, false))) {
1365 // Plugin name is expected to be: Smarty_[Type]_[Name]
1366 $_name_parts = explode('_', $plugin_name, 3);
1367 // class name must have three parts to be valid plugin
1368 // count($_name_parts) < 3 === !isset($_name_parts[2])
1369 if (!isset($_name_parts[2]) ||
strtolower($_name_parts[0]) !== 'smarty') {
1370 throw new SmartyException("plugin {$plugin_name} is not a valid name format");
1372 // if type is "internal", get plugin from sysplugins
1373 if (strtolower($_name_parts[1]) == 'internal') {
1374 $file = SMARTY_SYSPLUGINS_DIR
. strtolower($plugin_name) . '.php';
1375 if (file_exists($file)) {
1376 require_once($file);
1383 // plugin filename is expected to be: [type].[name].php
1384 $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php";
1386 $_stream_resolve_include_path = function_exists('stream_resolve_include_path');
1388 // loop through plugin dirs and find the plugin
1389 foreach ($this->getPluginsDir() as $_plugin_dir) {
1391 $_plugin_dir . $_plugin_filename,
1392 $_plugin_dir . strtolower($_plugin_filename),
1394 foreach ($names as $file) {
1395 if (file_exists($file)) {
1396 require_once($file);
1400 if ($this->use_include_path
&& !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
1401 // try PHP include_path
1402 if ($_stream_resolve_include_path) {
1403 $file = stream_resolve_include_path($file);
1405 $file = Smarty_Internal_Get_Include_Path
::getIncludePath($file);
1408 if ($file !== false) {
1409 require_once($file);
1421 * Compile all template files
1423 * @param string $extension file extension
1424 * @param bool $force_compile force all to recompile
1425 * @param int $time_limit
1426 * @param int $max_errors
1428 * @return integer number of template files recompiled
1430 public function compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
1432 return Smarty_Internal_Utility
::compileAllTemplates($extension, $force_compile, $time_limit, $max_errors, $this);
1436 * Compile all config files
1438 * @param string $extension file extension
1439 * @param bool $force_compile force all to recompile
1440 * @param int $time_limit
1441 * @param int $max_errors
1443 * @return integer number of template files recompiled
1445 public function compileAllConfig($extension = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null)
1447 return Smarty_Internal_Utility
::compileAllConfig($extension, $force_compile, $time_limit, $max_errors, $this);
1451 * Delete compiled template file
1453 * @param string $resource_name template name
1454 * @param string $compile_id compile id
1455 * @param integer $exp_time expiration time
1457 * @return integer number of template files deleted
1459 public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
1461 return Smarty_Internal_Utility
::clearCompiledTemplate($resource_name, $compile_id, $exp_time, $this);
1465 * Return array of tag/attributes of all tags used by an template
1467 * @param Smarty_Internal_Template $template
1469 * @return array of tag/attributes
1471 public function getTags(Smarty_Internal_Template
$template)
1473 return Smarty_Internal_Utility
::getTags($template);
1477 * Run installation test
1479 * @param array $errors Array to write errors into, rather than outputting them
1481 * @return boolean true if setup is fine, false if something is wrong
1483 public function testInstall(&$errors = null)
1485 return Smarty_Internal_Utility
::testInstall($this, $errors);
1489 * Error Handler to mute expected messages
1491 * @link http://php.net/set_error_handler
1493 * @param integer $errno Error level
1497 * @param $errcontext
1501 public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext)
1503 $_is_muted_directory = false;
1505 // add the SMARTY_DIR to the list of muted directories
1506 if (!isset(Smarty
::$_muted_directories[SMARTY_DIR
])) {
1507 $smarty_dir = realpath(SMARTY_DIR
);
1508 if ($smarty_dir !== false) {
1509 Smarty
::$_muted_directories[SMARTY_DIR
] = array(
1510 'file' => $smarty_dir,
1511 'length' => strlen($smarty_dir),
1516 // walk the muted directories and test against $errfile
1517 foreach (Smarty
::$_muted_directories as $key => &$dir) {
1519 // resolve directory and length for speedy comparisons
1520 $file = realpath($key);
1521 if ($file === false) {
1522 // this directory does not exist, remove and skip it
1523 unset(Smarty
::$_muted_directories[$key]);
1528 'length' => strlen($file),
1531 if (!strncmp($errfile, $dir['file'], $dir['length'])) {
1532 $_is_muted_directory = true;
1537 // pass to next error handler if this error did not occur inside SMARTY_DIR
1538 // or the error was within smarty but masked to be ignored
1539 if (!$_is_muted_directory ||
($errno && $errno & error_reporting())) {
1540 if (Smarty
::$_previous_error_handler) {
1541 return call_user_func(Smarty
::$_previous_error_handler, $errno, $errstr, $errfile, $errline, $errcontext);
1549 * Enable error handler to mute expected messages
1553 public static function muteExpectedErrors()
1556 error muting is done because some people implemented custom error_handlers using
1557 http://php.net/set_error_handler and for some reason did not understand the following paragraph:
1559 It is important to remember that the standard PHP error handler is completely bypassed for the
1560 error types specified by error_types unless the callback function returns FALSE.
1561 error_reporting() settings will have no effect and your error handler will be called regardless -
1562 however you are still able to read the current value of error_reporting and act appropriately.
1563 Of particular note is that this value will be 0 if the statement that caused the error was
1564 prepended by the @ error-control operator.
1566 Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include
1567 - @filemtime() is almost twice as fast as using an additional file_exists()
1568 - between file_exists() and filemtime() a possible race condition is opened,
1569 which does not exist using the simple @filemtime() approach.
1571 $error_handler = array('Smarty', 'mutingErrorHandler');
1572 $previous = set_error_handler($error_handler);
1575 if ($previous !== $error_handler) {
1576 Smarty
::$_previous_error_handler = $previous;
1581 * Disable error handler muting expected messages
1585 public static function unmuteExpectedErrors()
1587 restore_error_handler();
1591 // Check if we're running on windows
1592 Smarty
::$_IS_WINDOWS = strtoupper(substr(PHP_OS
, 0, 3)) === 'WIN';
1594 // let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8
1595 if (Smarty
::$_CHARSET !== 'UTF-8') {
1596 Smarty
::$_UTF8_MODIFIER = '';
1600 * Smarty exception class
1604 class SmartyException
extends Exception
1606 public static $escape = false;
1608 public function __toString()
1610 return ' --> Smarty: ' . (self
::$escape ?
htmlentities($this->message
) : $this->message
) . ' <-- ';
1615 * Smarty compiler exception class
1619 class SmartyCompilerException
extends SmartyException
1621 public function __toString()
1623 return ' --> Smarty Compiler: ' . $this->message
. ' <-- ';
1627 * The line number of the template error
1631 public $line = null;
1633 * The template source snippet relating to the error
1637 public $source = null;
1639 * The raw text of the error message
1643 public $desc = null;
1645 * The resource identifier or template name
1649 public $template = null;
1655 function smartyAutoload($class)
1657 $_class = strtolower($class);
1658 static $_classes = array(
1659 'smarty_config_source' => true,
1660 'smarty_config_compiled' => true,
1661 'smarty_security' => true,
1662 'smarty_cacheresource' => true,
1663 'smarty_cacheresource_custom' => true,
1664 'smarty_cacheresource_keyvaluestore' => true,
1665 'smarty_resource' => true,
1666 'smarty_resource_custom' => true,
1667 'smarty_resource_uncompiled' => true,
1668 'smarty_resource_recompiled' => true,
1671 if (!strncmp($_class, 'smarty_internal_', 16) ||
isset($_classes[$_class])) {
1672 include SMARTY_SYSPLUGINS_DIR
. $_class . '.php';