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