fix last commit
[GitHub/Stricted/Domain-Control-Panel.git] / lib / api / smarty / Smarty.class.php
1 <?php
2 /**
3 * Project: Smarty: the PHP compiling template engine
4 * File: Smarty.class.php
5 *
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 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * For questions, help, comments, discussion, etc., please join the
20 * Smarty mailing list. Send a blank e-mail to
21 * smarty-discussion-subscribe@googlegroups.com
22 *
23 * @link http://www.smarty.net/
24 * @copyright 2015 New Digital Group, Inc.
25 * @copyright 2015 Uwe Tews
26 * @author Monte Ohrt <monte at ohrt dot com>
27 * @author Uwe Tews
28 * @author Rodney Rehm
29 * @package Smarty
30 * @version 3.1-DEV
31 */
32
33 /**
34 * define shorthand directory separator constant
35 */
36 if (!defined('DS')) {
37 define('DS', DIRECTORY_SEPARATOR);
38 }
39
40 /**
41 * set SMARTY_DIR to absolute path to Smarty library files.
42 * Sets SMARTY_DIR only if user application has not already defined it.
43 */
44 if (!defined('SMARTY_DIR')) {
45 define('SMARTY_DIR', dirname(__FILE__) . DS);
46 }
47
48 /**
49 * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins.
50 * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it.
51 */
52 if (!defined('SMARTY_SYSPLUGINS_DIR')) {
53 define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DS);
54 }
55 if (!defined('SMARTY_PLUGINS_DIR')) {
56 define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS);
57 }
58 if (!defined('SMARTY_MBSTRING')) {
59 define('SMARTY_MBSTRING', function_exists('mb_get_info'));
60 }
61 if (!defined('SMARTY_RESOURCE_CHAR_SET')) {
62 // UTF-8 can only be done properly when mbstring is available!
63 /**
64 * @deprecated in favor of Smarty::$_CHARSET
65 */
66 define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1');
67 }
68 if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) {
69 /**
70 * @deprecated in favor of Smarty::$_DATE_FORMAT
71 */
72 define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y');
73 }
74
75 /**
76 * Try loading the Smmarty_Internal_Data class
77 * If we fail we must load Smarty's autoloader.
78 * Otherwise we may have a global autoloader like Composer
79 */
80 if (!class_exists('Smarty_Autoloader', false)) {
81 if (!class_exists('Smarty_Internal_Data', true)) {
82 require_once 'Autoloader.php';
83 Smarty_Autoloader::registerBC();
84 }
85 }
86
87 /**
88 * Load always needed external class files
89 */
90
91 if (!class_exists('Smarty_Internal_Data', false)) {
92 require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php';
93 }
94 require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php';
95 require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php';
96 require_once SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php';
97 require_once SMARTY_SYSPLUGINS_DIR . 'smarty_variable.php';
98 require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_source.php';
99
100 /**
101 * This is the main Smarty class
102 *
103 * @package Smarty
104 */
105 class Smarty extends Smarty_Internal_TemplateBase
106 {
107 /**#@+
108 * constant definitions
109 */
110
111 /**
112 * smarty version
113 */
114 const SMARTY_VERSION = '3.1.24';
115
116 /**
117 * define variable scopes
118 */
119 const SCOPE_LOCAL = 0;
120
121 const SCOPE_PARENT = 1;
122
123 const SCOPE_ROOT = 2;
124
125 const SCOPE_GLOBAL = 3;
126
127 /**
128 * define caching modes
129 */
130 const CACHING_OFF = 0;
131
132 const CACHING_LIFETIME_CURRENT = 1;
133
134 const CACHING_LIFETIME_SAVED = 2;
135
136 /**
137 * define constant for clearing cache files be saved expiration datees
138 */
139 const CLEAR_EXPIRED = - 1;
140
141 /**
142 * define compile check modes
143 */
144 const COMPILECHECK_OFF = 0;
145
146 const COMPILECHECK_ON = 1;
147
148 const COMPILECHECK_CACHEMISS = 2;
149
150 /**
151 * define debug modes
152 */
153 const DEBUG_OFF = 0;
154
155 const DEBUG_ON = 1;
156
157 const DEBUG_INDIVIDUAL = 2;
158
159 /**
160 * modes for handling of "<?php ... ?>" tags in templates.
161 */
162 const PHP_PASSTHRU = 0; //-> print tags as plain text
163
164 const PHP_QUOTE = 1; //-> escape tags as entities
165
166 const PHP_REMOVE = 2; //-> escape tags as entities
167
168 const PHP_ALLOW = 3; //-> escape tags as entities
169
170 /**
171 * filter types
172 */
173 const FILTER_POST = 'post';
174
175 const FILTER_PRE = 'pre';
176
177 const FILTER_OUTPUT = 'output';
178
179 const FILTER_VARIABLE = 'variable';
180
181 /**
182 * plugin types
183 */
184 const PLUGIN_FUNCTION = 'function';
185
186 const PLUGIN_BLOCK = 'block';
187
188 const PLUGIN_COMPILER = 'compiler';
189
190 const PLUGIN_MODIFIER = 'modifier';
191
192 const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler';
193
194 /**#@-*/
195
196 /**
197 * assigned global tpl vars
198 */
199 public static $global_tpl_vars = array();
200
201 /**
202 * error handler returned by set_error_hanlder() in Smarty::muteExpectedErrors()
203 */
204 public static $_previous_error_handler = null;
205
206 /**
207 * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors()
208 */
209 public static $_muted_directories = array('./templates_c/' => null,
210 './cache/' => null);
211
212 /**
213 * Flag denoting if Multibyte String functions are available
214 */
215 public static $_MBSTRING = SMARTY_MBSTRING;
216
217 /**
218 * The character set to adhere to (e.g. "UTF-8")
219 */
220 public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET;
221
222 /**
223 * The date format to be used internally
224 * (accepts date() and strftime())
225 */
226 public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT;
227
228 /**
229 * Flag denoting if PCRE should run in UTF-8 mode
230 */
231 public static $_UTF8_MODIFIER = 'u';
232
233 /**
234 * Flag denoting if operating system is windows
235 */
236 public static $_IS_WINDOWS = false;
237
238 /**#@+
239 * variables
240 */
241
242 /**
243 * auto literal on delimiters with whitspace
244 *
245 * @var boolean
246 */
247 public $auto_literal = true;
248
249 /**
250 * display error on not assigned variables
251 *
252 * @var boolean
253 */
254 public $error_unassigned = false;
255
256 /**
257 * look up relative filepaths in include_path
258 *
259 * @var boolean
260 */
261 public $use_include_path = false;
262
263 /**
264 * template directory
265 *
266 * @var array
267 */
268 private $template_dir = array('./templates/');
269
270 /**
271 * joined template directory string used in cache keys
272 *
273 * @var string
274 */
275 public $joined_template_dir = './templates/';
276
277 /**
278 * joined config directory string used in cache keys
279 *
280 * @var string
281 */
282 public $joined_config_dir = './configs/';
283
284 /**
285 * default template handler
286 *
287 * @var callable
288 */
289 public $default_template_handler_func = null;
290
291 /**
292 * default config handler
293 *
294 * @var callable
295 */
296 public $default_config_handler_func = null;
297
298 /**
299 * default plugin handler
300 *
301 * @var callable
302 */
303 public $default_plugin_handler_func = null;
304
305 /**
306 * compile directory
307 *
308 * @var string
309 */
310 private $compile_dir = './templates_c/';
311
312 /**
313 * plugins directory
314 *
315 * @var array
316 */
317 private $plugins_dir = null;
318
319 /**
320 * cache directory
321 *
322 * @var string
323 */
324 private $cache_dir = './cache/';
325
326 /**
327 * config directory
328 *
329 * @var array
330 */
331 private $config_dir = array('./configs/');
332
333 /**
334 * force template compiling?
335 *
336 * @var boolean
337 */
338 public $force_compile = false;
339
340 /**
341 * check template for modifications?
342 *
343 * @var boolean
344 */
345 public $compile_check = true;
346
347 /**
348 * use sub dirs for compiled/cached files?
349 *
350 * @var boolean
351 */
352 public $use_sub_dirs = false;
353
354 /**
355 * allow ambiguous resources (that are made unique by the resource handler)
356 *
357 * @var boolean
358 */
359 public $allow_ambiguous_resources = false;
360
361 /**
362 * merge compiled includes
363 *
364 * @var boolean
365 */
366 public $merge_compiled_includes = false;
367
368 /**
369 * template inheritance merge compiled includes
370 *
371 * @var boolean
372 */
373 public $inheritance_merge_compiled_includes = true;
374
375 /**
376 * force cache file creation
377 *
378 * @var boolean
379 */
380 public $force_cache = false;
381
382 /**
383 * template left-delimiter
384 *
385 * @var string
386 */
387 public $left_delimiter = "{";
388
389 /**
390 * template right-delimiter
391 *
392 * @var string
393 */
394 public $right_delimiter = "}";
395
396 /**#@+
397 * security
398 */
399 /**
400 * class name
401 * This should be instance of Smarty_Security.
402 *
403 * @var string
404 * @see Smarty_Security
405 */
406 public $security_class = 'Smarty_Security';
407
408 /**
409 * implementation of security class
410 *
411 * @var Smarty_Security
412 */
413 public $security_policy = null;
414
415 /**
416 * controls handling of PHP-blocks
417 *
418 * @var integer
419 */
420 public $php_handling = self::PHP_PASSTHRU;
421
422 /**
423 * controls if the php template file resource is allowed
424 *
425 * @var bool
426 */
427 public $allow_php_templates = false;
428
429 /**
430 * Should compiled-templates be prevented from being called directly?
431 * {@internal
432 * Currently used by Smarty_Internal_Template only.
433 * }}
434 *
435 * @var boolean
436 */
437 public $direct_access_security = true;
438
439 /**#@-*/
440 /**
441 * debug mode
442 * Setting this to true enables the debug-console.
443 *
444 * @var boolean
445 */
446 public $debugging = false;
447
448 /**
449 * This determines if debugging is enable-able from the browser.
450 * <ul>
451 * <li>NONE => no debugging control allowed</li>
452 * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
453 * </ul>
454 *
455 * @var string
456 */
457 public $debugging_ctrl = 'NONE';
458
459 /**
460 * Name of debugging URL-param.
461 * Only used when $debugging_ctrl is set to 'URL'.
462 * The name of the URL-parameter that activates debugging.
463 *
464 * @var string
465 */
466 public $smarty_debug_id = 'SMARTY_DEBUG';
467
468 /**
469 * Path of debug template.
470 *
471 * @var string
472 */
473 public $debug_tpl = null;
474
475 /**
476 * When set, smarty uses this value as error_reporting-level.
477 *
478 * @var int
479 */
480 public $error_reporting = null;
481
482 /**
483 * Internal flag for getTags()
484 *
485 * @var boolean
486 */
487 public $get_used_tags = false;
488
489 /**#@+
490 * config var settings
491 */
492
493 /**
494 * Controls whether variables with the same name overwrite each other.
495 *
496 * @var boolean
497 */
498 public $config_overwrite = true;
499
500 /**
501 * Controls whether config values of on/true/yes and off/false/no get converted to boolean.
502 *
503 * @var boolean
504 */
505 public $config_booleanize = true;
506
507 /**
508 * Controls whether hidden config sections/vars are read from the file.
509 *
510 * @var boolean
511 */
512 public $config_read_hidden = false;
513
514 /**#@-*/
515
516 /**#@+
517 * resource locking
518 */
519
520 /**
521 * locking concurrent compiles
522 *
523 * @var boolean
524 */
525 public $compile_locking = true;
526
527 /**
528 * Controls whether cache resources should emply locking mechanism
529 *
530 * @var boolean
531 */
532 public $cache_locking = false;
533
534 /**
535 * seconds to wait for acquiring a lock before ignoring the write lock
536 *
537 * @var float
538 */
539 public $locking_timeout = 10;
540
541 /**#@-*/
542
543 /**
544 * resource type used if none given
545 * Must be an valid key of $registered_resources.
546 *
547 * @var string
548 */
549 public $default_resource_type = 'file';
550
551 /**
552 * caching type
553 * Must be an element of $cache_resource_types.
554 *
555 * @var string
556 */
557 public $caching_type = 'file';
558
559 /**
560 * internal config properties
561 *
562 * @var array
563 */
564 public $properties = array();
565
566 /**
567 * config type
568 *
569 * @var string
570 */
571 public $default_config_type = 'file';
572
573 /**
574 * cached template objects
575 *
576 * @var array
577 */
578 public $source_objects = array();
579
580 /**
581 * cached template objects
582 *
583 * @var array
584 */
585 public $template_objects = array();
586
587 /**
588 * enable resource caching
589 *
590 * @var bool
591 */
592 public $resource_caching = false;
593
594 /**
595 * enable template resource caching
596 *
597 * @var bool
598 */
599 public $template_resource_caching = true;
600
601 /**
602 * check If-Modified-Since headers
603 *
604 * @var boolean
605 */
606 public $cache_modified_check = false;
607
608 /**
609 * registered plugins
610 *
611 * @var array
612 */
613 public $registered_plugins = array();
614
615 /**
616 * plugin search order
617 *
618 * @var array
619 */
620 public $plugin_search_order = array('function',
621 'block',
622 'compiler',
623 'class');
624
625 /**
626 * registered objects
627 *
628 * @var array
629 */
630 public $registered_objects = array();
631
632 /**
633 * registered classes
634 *
635 * @var array
636 */
637 public $registered_classes = array();
638
639 /**
640 * registered filters
641 *
642 * @var array
643 */
644 public $registered_filters = array();
645
646 /**
647 * registered resources
648 *
649 * @var array
650 */
651 public $registered_resources = array();
652
653 /**
654 * resource handler cache
655 *
656 * @var array
657 */
658 public $_resource_handlers = array();
659
660 /**
661 * registered cache resources
662 *
663 * @var array
664 */
665 public $registered_cache_resources = array();
666
667 /**
668 * cache resource handler cache
669 *
670 * @var array
671 */
672 public $_cacheresource_handlers = array();
673
674 /**
675 * autoload filter
676 *
677 * @var array
678 */
679 public $autoload_filters = array();
680
681 /**
682 * default modifier
683 *
684 * @var array
685 */
686 public $default_modifiers = array();
687
688 /**
689 * autoescape variable output
690 *
691 * @var boolean
692 */
693 public $escape_html = false;
694
695 /**
696 * global internal smarty vars
697 *
698 * @var array
699 */
700 public static $_smarty_vars = array();
701
702 /**
703 * start time for execution time calculation
704 *
705 * @var int
706 */
707 public $start_time = 0;
708
709 /**
710 * default file permissions
711 *
712 * @var int
713 */
714 public $_file_perms = 0644;
715
716 /**
717 * default dir permissions
718 *
719 * @var int
720 */
721 public $_dir_perms = 0771;
722
723 /**
724 * block tag hierarchy
725 *
726 * @var array
727 */
728 public $_tag_stack = array();
729
730 /**
731 * required by the compiler for BC
732 *
733 * @var string
734 */
735 public $_current_file = null;
736
737 /**
738 * internal flag to enable parser debugging
739 *
740 * @var bool
741 */
742 public $_parserdebug = false;
743
744 /**
745 * Cache of is_file results of loadPlugin()
746 *
747 * @var array
748 */
749 public $_is_file_cache = array();
750
751 /**#@-*/
752
753 /**
754 * Initialize new Smarty object
755 */
756 public function __construct()
757 {
758 if (is_callable('mb_internal_encoding')) {
759 mb_internal_encoding(Smarty::$_CHARSET);
760 }
761 $this->start_time = microtime(true);
762 // check default dirs for overloading
763 if ($this->template_dir[0] !== './templates/' || isset($this->template_dir[1])) {
764 $this->setTemplateDir($this->template_dir);
765 }
766 if ($this->config_dir[0] !== './configs/' || isset($this->config_dir[1])) {
767 $this->setConfigDir($this->config_dir);
768 }
769 if ($this->compile_dir !== './templates_c/') {
770 unset(self::$_muted_directories['./templates_c/']);
771 $this->setCompileDir($this->compile_dir);
772 }
773 if ($this->cache_dir !== './cache/') {
774 unset(self::$_muted_directories['./cache/']);
775 $this->setCacheDir($this->cache_dir);
776 }
777 if (isset($this->plugins_dir)) {
778 $this->setPluginsDir($this->plugins_dir);
779 } else {
780 $this->setPluginsDir(SMARTY_PLUGINS_DIR);
781 }
782 if (isset($_SERVER['SCRIPT_NAME'])) {
783 Smarty::$global_tpl_vars['SCRIPT_NAME'] = new Smarty_Variable($_SERVER['SCRIPT_NAME']);
784 }
785
786 // Check if we're running on windows
787 Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
788
789 // let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8
790 if (Smarty::$_CHARSET !== 'UTF-8') {
791 Smarty::$_UTF8_MODIFIER = '';
792 }
793 }
794
795 /**
796 * fetches a rendered Smarty template
797 *
798 * @param string $template the resource handle of the template file or template object
799 * @param mixed $cache_id cache id to be used with this template
800 * @param mixed $compile_id compile id to be used with this template
801 * @param object $parent next higher level of Smarty variables
802 * @param bool $display true: display, false: fetch
803 * @param bool $merge_tpl_vars not used - left for BC
804 * @param bool $no_output_filter not used - left for BC
805 *
806 * @throws Exception
807 * @throws SmartyException
808 * @return string rendered template output
809 */
810 public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false)
811 {
812 if ($cache_id !== null && is_object($cache_id)) {
813 $parent = $cache_id;
814 $cache_id = null;
815 }
816 if ($parent === null) {
817 $parent = $this;
818 }
819 // get template object
820 $_template = is_object($template) ? $template : $this->createTemplate($template, $cache_id, $compile_id, $parent, false);
821 // set caching in template object
822 $_template->caching = $this->caching;
823 // fetch template content
824 return $_template->render(true, false, $display);
825 }
826
827 /**
828 * displays a Smarty template
829 *
830 * @param string $template the resource handle of the template file or template object
831 * @param mixed $cache_id cache id to be used with this template
832 * @param mixed $compile_id compile id to be used with this template
833 * @param object $parent next higher level of Smarty variables
834 */
835 public function display($template = null, $cache_id = null, $compile_id = null, $parent = null)
836 {
837 // display template
838 $this->fetch($template, $cache_id, $compile_id, $parent, true);
839 }
840
841 /**
842 * Check if a template resource exists
843 *
844 * @param string $resource_name template name
845 *
846 * @return boolean status
847 */
848 public function templateExists($resource_name)
849 {
850 // create template object
851 $save = $this->template_objects;
852 $tpl = new $this->template_class($resource_name, $this);
853 // check if it does exists
854 $result = $tpl->source->exists;
855 $this->template_objects = $save;
856
857 return $result;
858 }
859
860 /**
861 * Returns a single or all global variables
862 *
863 * @param string $varname variable name or null
864 *
865 * @return string variable value or or array of variables
866 */
867 public function getGlobal($varname = null)
868 {
869 if (isset($varname)) {
870 if (isset(self::$global_tpl_vars[$varname])) {
871 return self::$global_tpl_vars[$varname]->value;
872 } else {
873 return '';
874 }
875 } else {
876 $_result = array();
877 foreach (self::$global_tpl_vars AS $key => $var) {
878 $_result[$key] = $var->value;
879 }
880
881 return $_result;
882 }
883 }
884
885 /**
886 * Empty cache folder
887 *
888 * @param integer $exp_time expiration time
889 * @param string $type resource type
890 *
891 * @return integer number of cache files deleted
892 */
893 public function clearAllCache($exp_time = null, $type = null)
894 {
895 // load cache resource and call clearAll
896 $_cache_resource = Smarty_CacheResource::load($this, $type);
897 Smarty_CacheResource::invalidLoadedCache($this);
898
899 return $_cache_resource->clearAll($this, $exp_time);
900 }
901
902 /**
903 * Empty cache for a specific template
904 *
905 * @param string $template_name template name
906 * @param string $cache_id cache id
907 * @param string $compile_id compile id
908 * @param integer $exp_time expiration time
909 * @param string $type resource type
910 *
911 * @return integer number of cache files deleted
912 */
913 public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
914 {
915 // load cache resource and call clear
916 $_cache_resource = Smarty_CacheResource::load($this, $type);
917 Smarty_CacheResource::invalidLoadedCache($this);
918
919 return $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time);
920 }
921
922 /**
923 * Loads security class and enables security
924 *
925 * @param string|Smarty_Security $security_class if a string is used, it must be class-name
926 *
927 * @return Smarty current Smarty instance for chaining
928 * @throws SmartyException when an invalid class name is provided
929 */
930 public function enableSecurity($security_class = null)
931 {
932 if ($security_class instanceof Smarty_Security) {
933 $this->security_policy = $security_class;
934
935 return $this;
936 } elseif (is_object($security_class)) {
937 throw new SmartyException("Class '" . get_class($security_class) . "' must extend Smarty_Security.");
938 }
939 if ($security_class == null) {
940 $security_class = $this->security_class;
941 }
942 if (!class_exists($security_class)) {
943 throw new SmartyException("Security class '$security_class' is not defined");
944 } elseif ($security_class !== 'Smarty_Security' && !is_subclass_of($security_class, 'Smarty_Security')) {
945 throw new SmartyException("Class '$security_class' must extend Smarty_Security.");
946 } else {
947 $this->security_policy = new $security_class($this);
948 }
949
950 return $this;
951 }
952
953 /**
954 * Disable security
955 *
956 * @return Smarty current Smarty instance for chaining
957 */
958 public function disableSecurity()
959 {
960 $this->security_policy = null;
961
962 return $this;
963 }
964
965 /**
966 * Set template directory
967 *
968 * @param string|array $template_dir directory(s) of template sources
969 *
970 * @return Smarty current Smarty instance for chaining
971 */
972 public function setTemplateDir($template_dir)
973 {
974 $this->template_dir = array();
975 foreach ((array) $template_dir as $k => $v) {
976 $this->template_dir[$k] = rtrim(strtr($v, '\\', '/'), '/') . '/';
977 }
978 $this->joined_template_dir = join(' # ', $this->template_dir);
979 return $this;
980 }
981
982 /**
983 * Add template directory(s)
984 *
985 * @param string|array $template_dir directory(s) of template sources
986 * @param string $key of the array element to assign the template dir to
987 *
988 * @return Smarty current Smarty instance for chaining
989 * @throws SmartyException when the given template directory is not valid
990 */
991 public function addTemplateDir($template_dir, $key = null)
992 {
993 $this->_addDir('template_dir', $template_dir, $key);
994 $this->joined_template_dir = join(' # ', $this->template_dir);
995 return $this;
996 }
997
998 /**
999 * Get template directories
1000 *
1001 * @param mixed $index index of directory to get, null to get all
1002 *
1003 * @return array|string list of template directories, or directory of $index
1004 */
1005 public function getTemplateDir($index = null)
1006 {
1007 if ($index !== null) {
1008 return isset($this->template_dir[$index]) ? $this->template_dir[$index] : null;
1009 }
1010 return (array) $this->template_dir;
1011 }
1012
1013 /**
1014 * Set config directory
1015 *
1016 * @param $config_dir
1017 *
1018 * @return Smarty current Smarty instance for chaining
1019 */
1020 public function setConfigDir($config_dir)
1021 {
1022 $this->config_dir = array();
1023 foreach ((array) $config_dir as $k => $v) {
1024 $this->config_dir[$k] = rtrim(strtr($v, '\\', '/'), '/') . '/';
1025 }
1026 $this->joined_config_dir = join(' # ', $this->config_dir);
1027 return $this;
1028 }
1029
1030 /**
1031 * Add config directory(s)
1032 *
1033 * @param string|array $config_dir directory(s) of config sources
1034 * @param mixed $key key of the array element to assign the config dir to
1035 *
1036 * @return Smarty current Smarty instance for chaining
1037 */
1038 public function addConfigDir($config_dir, $key = null)
1039 {
1040 $this->_addDir('config_dir', $config_dir, $key);
1041 $this->joined_config_dir = join(' # ', $this->config_dir);
1042 return $this;
1043 }
1044
1045 /**
1046 * Get config directory
1047 *
1048 * @param mixed $index index of directory to get, null to get all
1049 *
1050 * @return array|string configuration directory
1051 */
1052 public function getConfigDir($index = null)
1053 {
1054 if ($index !== null) {
1055 return isset($this->config_dir[$index]) ? $this->config_dir[$index] : null;
1056 }
1057 return (array) $this->config_dir;
1058 }
1059
1060 /**
1061 * Set plugins directory
1062 *
1063 * @param string|array $plugins_dir directory(s) of plugins
1064 *
1065 * @return Smarty current Smarty instance for chaining
1066 */
1067 public function setPluginsDir($plugins_dir)
1068 {
1069 $this->plugins_dir = array();
1070 foreach ((array) $plugins_dir as $k => $v) {
1071 $this->plugins_dir[$k] = rtrim(strtr($v, '\\', '/'), '/') . '/';
1072 }
1073 $this->_is_file_cache = array();
1074 return $this;
1075 }
1076
1077 /**
1078 * Adds directory of plugin files
1079 *
1080 * @param $plugins_dir
1081 *
1082 * @return Smarty current Smarty instance for chaining
1083 */
1084 public function addPluginsDir($plugins_dir)
1085 {
1086 $this->_addDir('plugins_dir', $plugins_dir);
1087 $this->plugins_dir = array_unique($this->plugins_dir);
1088 $this->_is_file_cache = array();
1089 return $this;
1090 }
1091
1092 /**
1093 * Get plugin directories
1094 *
1095 * @return array list of plugin directories
1096 */
1097 public function getPluginsDir()
1098 {
1099 return (array) $this->plugins_dir;
1100 }
1101
1102 /**
1103 * Set compile directory
1104 *
1105 * @param string $compile_dir directory to store compiled templates in
1106 *
1107 * @return Smarty current Smarty instance for chaining
1108 */
1109 public function setCompileDir($compile_dir)
1110 {
1111 $this->compile_dir = rtrim(strtr($compile_dir, '\\', '/'), '/') . '/';
1112 if (!isset(Smarty::$_muted_directories[$this->compile_dir])) {
1113 Smarty::$_muted_directories[$this->compile_dir] = null;
1114 }
1115
1116 return $this;
1117 }
1118
1119 /**
1120 * Get compiled directory
1121 *
1122 * @return string path to compiled templates
1123 */
1124 public function getCompileDir()
1125 {
1126 return $this->compile_dir;
1127 }
1128
1129 /**
1130 * Set cache directory
1131 *
1132 * @param string $cache_dir directory to store cached templates in
1133 *
1134 * @return Smarty current Smarty instance for chaining
1135 */
1136 public function setCacheDir($cache_dir)
1137 {
1138 $this->cache_dir = rtrim(strtr($cache_dir, '\\', '/'), '/') . '/';
1139 if (!isset(Smarty::$_muted_directories[$this->cache_dir])) {
1140 Smarty::$_muted_directories[$this->cache_dir] = null;
1141 }
1142
1143 return $this;
1144 }
1145
1146 /**
1147 * Get cache directory
1148 *
1149 * @return string path of cache directory
1150 */
1151 public function getCacheDir()
1152 {
1153 return $this->cache_dir;
1154 }
1155
1156 /**
1157 * add directories to given property name
1158 *
1159 * @param string $dirName directory property name
1160 * @param string|array $dir directory string or array of strings
1161 * @param mixed $key optional key
1162 */
1163 private function _addDir($dirName, $dir, $key = null)
1164 {
1165 // make sure we're dealing with an array
1166 $this->$dirName = (array) $this->$dirName;
1167
1168 if (is_array($dir)) {
1169 foreach ($dir as $k => $v) {
1170 $v = rtrim(strtr($v, '\\', '/'), '/') . '/';
1171 if (is_int($k)) {
1172 // indexes are not merged but appended
1173 $this->{$dirName}[] = $v;
1174 } else {
1175 // string indexes are overridden
1176 $this->{$dirName}[$k] = $v;
1177 }
1178 }
1179 } else {
1180 $v = rtrim(strtr($dir, '\\', '/'), '/') . '/';
1181 if ($key !== null) {
1182 // override directory at specified index
1183 $this->{$dirName}[$key] = $v;
1184 } else {
1185 // append new directory
1186 $this->{$dirName}[] = $v;
1187 }
1188 }
1189 }
1190
1191 /**
1192 * Set default modifiers
1193 *
1194 * @param array|string $modifiers modifier or list of modifiers to set
1195 *
1196 * @return Smarty current Smarty instance for chaining
1197 */
1198 public function setDefaultModifiers($modifiers)
1199 {
1200 $this->default_modifiers = (array) $modifiers;
1201
1202 return $this;
1203 }
1204
1205 /**
1206 * Add default modifiers
1207 *
1208 * @param array|string $modifiers modifier or list of modifiers to add
1209 *
1210 * @return Smarty current Smarty instance for chaining
1211 */
1212 public function addDefaultModifiers($modifiers)
1213 {
1214 if (is_array($modifiers)) {
1215 $this->default_modifiers = array_merge($this->default_modifiers, $modifiers);
1216 } else {
1217 $this->default_modifiers[] = $modifiers;
1218 }
1219
1220 return $this;
1221 }
1222
1223 /**
1224 * Get default modifiers
1225 *
1226 * @return array list of default modifiers
1227 */
1228 public function getDefaultModifiers()
1229 {
1230 return $this->default_modifiers;
1231 }
1232
1233 /**
1234 * Set autoload filters
1235 *
1236 * @param array $filters filters to load automatically
1237 * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters'
1238 * keys as the appropriate types
1239 *
1240 * @return Smarty current Smarty instance for chaining
1241 */
1242 public function setAutoloadFilters($filters, $type = null)
1243 {
1244 if ($type !== null) {
1245 $this->autoload_filters[$type] = (array) $filters;
1246 } else {
1247 $this->autoload_filters = (array) $filters;
1248 }
1249
1250 return $this;
1251 }
1252
1253 /**
1254 * Add autoload filters
1255 *
1256 * @param array $filters filters to load automatically
1257 * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters'
1258 * keys as the appropriate types
1259 *
1260 * @return Smarty current Smarty instance for chaining
1261 */
1262 public function addAutoloadFilters($filters, $type = null)
1263 {
1264 if ($type !== null) {
1265 if (!empty($this->autoload_filters[$type])) {
1266 $this->autoload_filters[$type] = array_merge($this->autoload_filters[$type], (array) $filters);
1267 } else {
1268 $this->autoload_filters[$type] = (array) $filters;
1269 }
1270 } else {
1271 foreach ((array) $filters as $key => $value) {
1272 if (!empty($this->autoload_filters[$key])) {
1273 $this->autoload_filters[$key] = array_merge($this->autoload_filters[$key], (array) $value);
1274 } else {
1275 $this->autoload_filters[$key] = (array) $value;
1276 }
1277 }
1278 }
1279
1280 return $this;
1281 }
1282
1283 /**
1284 * Get autoload filters
1285 *
1286 * @param string $type type of filter to get autoloads for. Defaults to all autoload filters
1287 *
1288 * @return array array( 'type1' => array( 'filter1', 'filter2', … ) ) or array( 'filter1', 'filter2', …) if $type
1289 * was specified
1290 */
1291 public function getAutoloadFilters($type = null)
1292 {
1293 if ($type !== null) {
1294 return isset($this->autoload_filters[$type]) ? $this->autoload_filters[$type] : array();
1295 }
1296
1297 return $this->autoload_filters;
1298 }
1299
1300 /**
1301 * return name of debugging template
1302 *
1303 * @return string
1304 */
1305 public function getDebugTemplate()
1306 {
1307 return $this->debug_tpl;
1308 }
1309
1310 /**
1311 * set the debug template
1312 *
1313 * @param string $tpl_name
1314 *
1315 * @return Smarty current Smarty instance for chaining
1316 * @throws SmartyException if file is not readable
1317 */
1318 public function setDebugTemplate($tpl_name)
1319 {
1320 if (!is_readable($tpl_name)) {
1321 throw new SmartyException("Unknown file '{$tpl_name}'");
1322 }
1323 $this->debug_tpl = $tpl_name;
1324
1325 return $this;
1326 }
1327
1328 /**
1329 * creates a template object
1330 *
1331 * @param string $template the resource handle of the template file
1332 * @param mixed $cache_id cache id to be used with this template
1333 * @param mixed $compile_id compile id to be used with this template
1334 * @param object $parent next higher level of Smarty variables
1335 * @param boolean $do_clone flag is Smarty object shall be cloned
1336 *
1337 * @return object template object
1338 */
1339 public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true)
1340 {
1341 if ($cache_id !== null && (is_object($cache_id) || is_array($cache_id))) {
1342 $parent = $cache_id;
1343 $cache_id = null;
1344 }
1345 if ($parent !== null && is_array($parent)) {
1346 $data = $parent;
1347 $parent = null;
1348 } else {
1349 $data = null;
1350 }
1351 $_templateId = $this->getTemplateId($template, $cache_id, $compile_id);
1352 if (isset($this->template_objects[$_templateId])) {
1353 if ($do_clone) {
1354 $tpl = clone $this->template_objects[$_templateId];
1355 $tpl->smarty = clone $tpl->smarty;
1356 } else {
1357 $tpl = $this->template_objects[$_templateId];
1358 }
1359 $tpl->parent = $parent;
1360 $tpl->tpl_vars = array();
1361 $tpl->config_vars = array();
1362 } else {
1363 $tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id);
1364 if ($do_clone) {
1365 $tpl->smarty = clone $tpl->smarty;
1366 }
1367 $tpl->templateId = $_templateId;
1368 }
1369 // fill data if present
1370 if (!empty($data) && is_array($data)) {
1371 // set up variable values
1372 foreach ($data as $_key => $_val) {
1373 $tpl->tpl_vars[$_key] = new Smarty_Variable($_val);
1374 }
1375 }
1376 if ($this->debugging) {
1377 Smarty_Internal_Debug::register_template($tpl);
1378 }
1379 return $tpl;
1380 }
1381
1382 /**
1383 * Takes unknown classes and loads plugin files for them
1384 * class name format: Smarty_PluginType_PluginName
1385 * plugin filename format: plugintype.pluginname.php
1386 *
1387 * @param string $plugin_name class plugin name to load
1388 * @param bool $check check if already loaded
1389 *
1390 * @throws SmartyException
1391 * @return string |boolean filepath of loaded file or false
1392 */
1393 public function loadPlugin($plugin_name, $check = true)
1394 {
1395 // if function or class exists, exit silently (already loaded)
1396 if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) {
1397 return true;
1398 }
1399 // Plugin name is expected to be: Smarty_[Type]_[Name]
1400 $_name_parts = explode('_', $plugin_name, 3);
1401 // class name must have three parts to be valid plugin
1402 // count($_name_parts) < 3 === !isset($_name_parts[2])
1403 if (!isset($_name_parts[2]) || strtolower($_name_parts[0]) !== 'smarty') {
1404 throw new SmartyException("plugin {$plugin_name} is not a valid name format");
1405 }
1406 // if type is "internal", get plugin from sysplugins
1407 if (strtolower($_name_parts[1]) == 'internal') {
1408 $file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php';
1409 if (isset($this->_is_file_cache[$file]) ? $this->_is_file_cache[$file] : $this->_is_file_cache[$file] = is_file($file)) {
1410 require_once($file);
1411 return $file;
1412 } else {
1413 return false;
1414 }
1415 }
1416 // plugin filename is expected to be: [type].[name].php
1417 $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php";
1418
1419 $_stream_resolve_include_path = function_exists('stream_resolve_include_path');
1420
1421 // loop through plugin dirs and find the plugin
1422 foreach ($this->getPluginsDir() as $_plugin_dir) {
1423 $names = array($_plugin_dir . $_plugin_filename,
1424 $_plugin_dir . strtolower($_plugin_filename),);
1425 foreach ($names as $file) {
1426 if (isset($this->_is_file_cache[$file]) ? $this->_is_file_cache[$file] : $this->_is_file_cache[$file] = is_file($file)) {
1427 require_once($file);
1428 return $file;
1429 }
1430 if ($this->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
1431 // try PHP include_path
1432 if ($_stream_resolve_include_path) {
1433 $file = stream_resolve_include_path($file);
1434 } else {
1435 $file = Smarty_Internal_Get_Include_Path::getIncludePath($file);
1436 }
1437
1438 if ($file !== false) {
1439 require_once($file);
1440
1441 return $file;
1442 }
1443 }
1444 }
1445 }
1446 // no plugin loaded
1447 return false;
1448 }
1449
1450 /**
1451 * Compile all template files
1452 *
1453 * @param string $extension file extension
1454 * @param bool $force_compile force all to recompile
1455 * @param int $time_limit
1456 * @param int $max_errors
1457 *
1458 * @return integer number of template files recompiled
1459 */
1460 public function compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
1461 {
1462 return Smarty_Internal_Utility::compileAllTemplates($extension, $force_compile, $time_limit, $max_errors, $this);
1463 }
1464
1465 /**
1466 * Compile all config files
1467 *
1468 * @param string $extension file extension
1469 * @param bool $force_compile force all to recompile
1470 * @param int $time_limit
1471 * @param int $max_errors
1472 *
1473 * @return integer number of template files recompiled
1474 */
1475 public function compileAllConfig($extension = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null)
1476 {
1477 return Smarty_Internal_Utility::compileAllConfig($extension, $force_compile, $time_limit, $max_errors, $this);
1478 }
1479
1480 /**
1481 * Delete compiled template file
1482 *
1483 * @param string $resource_name template name
1484 * @param string $compile_id compile id
1485 * @param integer $exp_time expiration time
1486 *
1487 * @return integer number of template files deleted
1488 */
1489 public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
1490 {
1491 return Smarty_Internal_Utility::clearCompiledTemplate($resource_name, $compile_id, $exp_time, $this);
1492 }
1493
1494 /**
1495 * Return array of tag/attributes of all tags used by an template
1496 *
1497 * @param Smarty_Internal_Template $template
1498 *
1499 * @return array of tag/attributes
1500 */
1501 public function getTags(Smarty_Internal_Template $template)
1502 {
1503 return Smarty_Internal_Utility::getTags($template);
1504 }
1505
1506 /**
1507 * Run installation test
1508 *
1509 * @param array $errors Array to write errors into, rather than outputting them
1510 *
1511 * @return boolean true if setup is fine, false if something is wrong
1512 */
1513 public function testInstall(&$errors = null)
1514 {
1515 return Smarty_Internal_TestInstall::testInstall($this, $errors);
1516 }
1517
1518 /**
1519 * @param boolean $compile_check
1520 */
1521 public function setCompileCheck($compile_check)
1522 {
1523 $this->compile_check = $compile_check;
1524 }
1525
1526 /**
1527 * @param boolean $use_sub_dirs
1528 */
1529 public function setUseSubDirs($use_sub_dirs)
1530 {
1531 $this->use_sub_dirs = $use_sub_dirs;
1532 }
1533
1534 /**
1535 * @param boolean $caching
1536 */
1537 public function setCaching($caching)
1538 {
1539 $this->caching = $caching;
1540 }
1541
1542 /**
1543 * @param int $cache_lifetime
1544 */
1545 public function setCacheLifetime($cache_lifetime)
1546 {
1547 $this->cache_lifetime = $cache_lifetime;
1548 }
1549
1550 /**
1551 * @param string $compile_id
1552 */
1553 public function setCompileId($compile_id)
1554 {
1555 $this->compile_id = $compile_id;
1556 }
1557
1558 /**
1559 * @param string $cache_id
1560 */
1561 public function setCacheId($cache_id)
1562 {
1563 $this->cache_id = $cache_id;
1564 }
1565
1566 /**
1567 * @param int $error_reporting
1568 */
1569 public function setErrorReporting($error_reporting)
1570 {
1571 $this->error_reporting = $error_reporting;
1572 }
1573
1574 /**
1575 * @param boolean $escape_html
1576 */
1577 public function setEscapeHtml($escape_html)
1578 {
1579 $this->escape_html = $escape_html;
1580 }
1581
1582 /**
1583 * @param boolean $auto_literal
1584 */
1585 public function setAutoLiteral($auto_literal)
1586 {
1587 $this->auto_literal = $auto_literal;
1588 }
1589
1590 /**
1591 * @param boolean $force_compile
1592 */
1593 public function setForceCompile($force_compile)
1594 {
1595 $this->force_compile = $force_compile;
1596 }
1597
1598 /**
1599 * @param boolean $merge_compiled_includes
1600 */
1601 public function setMergeCompiledIncludes($merge_compiled_includes)
1602 {
1603 $this->merge_compiled_includes = $merge_compiled_includes;
1604 }
1605
1606 /**
1607 * @param string $left_delimiter
1608 */
1609 public function setLeftDelimiter($left_delimiter)
1610 {
1611 $this->left_delimiter = $left_delimiter;
1612 }
1613
1614 /**
1615 * @param string $right_delimiter
1616 */
1617 public function setRightDelimiter($right_delimiter)
1618 {
1619 $this->right_delimiter = $right_delimiter;
1620 }
1621
1622 /**
1623 * @param boolean $debugging
1624 */
1625 public function setDebugging($debugging)
1626 {
1627 $this->debugging = $debugging;
1628 }
1629
1630 /**
1631 * @param boolean $config_overwrite
1632 */
1633 public function setConfigOverwrite($config_overwrite)
1634 {
1635 $this->config_overwrite = $config_overwrite;
1636 }
1637
1638 /**
1639 * @param boolean $config_booleanize
1640 */
1641 public function setConfigBooleanize($config_booleanize)
1642 {
1643 $this->config_booleanize = $config_booleanize;
1644 }
1645
1646 /**
1647 * @param boolean $config_read_hidden
1648 */
1649 public function setConfigReadHidden($config_read_hidden)
1650 {
1651 $this->config_read_hidden = $config_read_hidden;
1652 }
1653
1654 /**
1655 * @param boolean $compile_locking
1656 */
1657 public function setCompileLocking($compile_locking)
1658 {
1659 $this->compile_locking = $compile_locking;
1660 }
1661
1662 /**
1663 * Class destructor
1664 */
1665 public function __destruct()
1666 {
1667 // intentionally left blank
1668 }
1669
1670 /**
1671 * <<magic>> Generic getter.
1672 * Calls the appropriate getter function.
1673 * Issues an E_USER_NOTICE if no valid getter is found.
1674 *
1675 * @param string $name property name
1676 *
1677 * @return mixed
1678 */
1679 public function __get($name)
1680 {
1681 $allowed = array('template_dir' => 'getTemplateDir',
1682 'config_dir' => 'getConfigDir',
1683 'plugins_dir' => 'getPluginsDir',
1684 'compile_dir' => 'getCompileDir',
1685 'cache_dir' => 'getCacheDir',);
1686
1687 if (isset($allowed[$name])) {
1688 return $this->{$allowed[$name]}();
1689 } else {
1690 trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
1691 }
1692 }
1693
1694 /**
1695 * <<magic>> Generic setter.
1696 * Calls the appropriate setter function.
1697 * Issues an E_USER_NOTICE if no valid setter is found.
1698 *
1699 * @param string $name property name
1700 * @param mixed $value parameter passed to setter
1701 */
1702 public function __set($name, $value)
1703 {
1704 $allowed = array('template_dir' => 'setTemplateDir',
1705 'config_dir' => 'setConfigDir',
1706 'plugins_dir' => 'setPluginsDir',
1707 'compile_dir' => 'setCompileDir',
1708 'cache_dir' => 'setCacheDir',);
1709
1710 if (isset($allowed[$name])) {
1711 $this->{$allowed[$name]}($value);
1712 } else {
1713 trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
1714 }
1715 }
1716
1717 /**
1718 * Error Handler to mute expected messages
1719 *
1720 * @link http://php.net/set_error_handler
1721 *
1722 * @param integer $errno Error level
1723 * @param $errstr
1724 * @param $errfile
1725 * @param $errline
1726 * @param $errcontext
1727 *
1728 * @return boolean
1729 */
1730 public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext)
1731 {
1732 $_is_muted_directory = false;
1733
1734 // add the SMARTY_DIR to the list of muted directories
1735 if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) {
1736 $smarty_dir = realpath(SMARTY_DIR);
1737 if ($smarty_dir !== false) {
1738 Smarty::$_muted_directories[SMARTY_DIR] = array('file' => $smarty_dir,
1739 'length' => strlen($smarty_dir),);
1740 }
1741 }
1742
1743 // walk the muted directories and test against $errfile
1744 foreach (Smarty::$_muted_directories as $key => &$dir) {
1745 if (!$dir) {
1746 // resolve directory and length for speedy comparisons
1747 $file = realpath($key);
1748 if ($file === false) {
1749 // this directory does not exist, remove and skip it
1750 unset(Smarty::$_muted_directories[$key]);
1751 continue;
1752 }
1753 $dir = array('file' => $file,
1754 'length' => strlen($file),);
1755 }
1756 if (!strncmp($errfile, $dir['file'], $dir['length'])) {
1757 $_is_muted_directory = true;
1758 break;
1759 }
1760 }
1761
1762 // pass to next error handler if this error did not occur inside SMARTY_DIR
1763 // or the error was within smarty but masked to be ignored
1764 if (!$_is_muted_directory || ($errno && $errno & error_reporting())) {
1765 if (Smarty::$_previous_error_handler) {
1766 return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline, $errcontext);
1767 } else {
1768 return false;
1769 }
1770 }
1771 }
1772
1773 /**
1774 * Enable error handler to mute expected messages
1775 *
1776 * @return void
1777 */
1778 public static function muteExpectedErrors()
1779 {
1780 /*
1781 error muting is done because some people implemented custom error_handlers using
1782 http://php.net/set_error_handler and for some reason did not understand the following paragraph:
1783
1784 It is important to remember that the standard PHP error handler is completely bypassed for the
1785 error types specified by error_types unless the callback function returns FALSE.
1786 error_reporting() settings will have no effect and your error handler will be called regardless -
1787 however you are still able to read the current value of error_reporting and act appropriately.
1788 Of particular note is that this value will be 0 if the statement that caused the error was
1789 prepended by the @ error-control operator.
1790
1791 Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include
1792 - @filemtime() is almost twice as fast as using an additional file_exists()
1793 - between file_exists() and filemtime() a possible race condition is opened,
1794 which does not exist using the simple @filemtime() approach.
1795 */
1796 $error_handler = array('Smarty',
1797 'mutingErrorHandler');
1798 $previous = set_error_handler($error_handler);
1799
1800 // avoid dead loops
1801 if ($previous !== $error_handler) {
1802 Smarty::$_previous_error_handler = $previous;
1803 }
1804 }
1805
1806 /**
1807 * Disable error handler muting expected messages
1808 *
1809 * @return void
1810 */
1811 public static function unmuteExpectedErrors()
1812 {
1813 restore_error_handler();
1814 }
1815 }