Smarty.class.php 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530
  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 2016 New Digital Group, Inc.
  25. * @copyright 2016 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.30
  31. */
  32. /**
  33. * define shorthand directory separator constant
  34. */
  35. if (!defined('DS')) {
  36. define('DS', DIRECTORY_SEPARATOR);
  37. }
  38. /**
  39. * set SMARTY_DIR to absolute path to Smarty library files.
  40. * Sets SMARTY_DIR only if user application has not already defined it.
  41. */
  42. if (!defined('SMARTY_DIR')) {
  43. define('SMARTY_DIR', dirname(__FILE__) . DS);
  44. }
  45. /**
  46. * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins.
  47. * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it.
  48. */
  49. if (!defined('SMARTY_SYSPLUGINS_DIR')) {
  50. define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DS);
  51. }
  52. if (!defined('SMARTY_PLUGINS_DIR')) {
  53. define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS);
  54. }
  55. if (!defined('SMARTY_MBSTRING')) {
  56. define('SMARTY_MBSTRING', function_exists('mb_get_info'));
  57. }
  58. if (!defined('SMARTY_RESOURCE_CHAR_SET')) {
  59. // UTF-8 can only be done properly when mbstring is available!
  60. /**
  61. * @deprecated in favor of Smarty::$_CHARSET
  62. */
  63. define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1');
  64. }
  65. if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) {
  66. /**
  67. * @deprecated in favor of Smarty::$_DATE_FORMAT
  68. */
  69. define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y');
  70. }
  71. /**
  72. * Try loading the Smarty_Internal_Data class
  73. * If we fail we must load Smarty's autoloader.
  74. * Otherwise we may have a global autoloader like Composer
  75. */
  76. if (!class_exists('Smarty_Autoloader', false)) {
  77. if (!class_exists('Smarty_Internal_Data', true)) {
  78. require_once dirname(__FILE__) . '/Autoloader.php';
  79. Smarty_Autoloader::registerBC();
  80. }
  81. }
  82. /**
  83. * Load always needed external class files
  84. */
  85. if (!class_exists('Smarty_Internal_Data', false)) {
  86. require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php';
  87. }
  88. require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_extension_handler.php';
  89. require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php';
  90. require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php';
  91. require_once SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php';
  92. require_once SMARTY_SYSPLUGINS_DIR . 'smarty_variable.php';
  93. require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_source.php';
  94. require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_resource_base.php';
  95. /**
  96. * This is the main Smarty class
  97. *
  98. * @package Smarty
  99. *
  100. * The following methods will be dynamically loaded by the extension handler when they are called.
  101. * They are located in a corresponding Smarty_Internal_Method_xxxx class
  102. *
  103. * @method int clearAllCache(int $exp_time = null, string $type = null)
  104. * @method int clearCache(string $template_name, string $cache_id = null, string $compile_id = null, int $exp_time = null, string $type = null)
  105. * @method int compileAllTemplates(string $extension = '.tpl', bool $force_compile = false, int $time_limit = 0, int $max_errors = null)
  106. * @method int compileAllConfig(string $extension = '.conf', bool $force_compile = false, int $time_limit = 0, int $max_errors = null)
  107. * @method int clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
  108. */
  109. class Smarty extends Smarty_Internal_TemplateBase
  110. {
  111. /**#@+
  112. * constant definitions
  113. */
  114. /**
  115. * smarty version
  116. */
  117. const SMARTY_VERSION = '3.1.30';
  118. /**
  119. * define variable scopes
  120. */
  121. const SCOPE_LOCAL = 1;
  122. const SCOPE_PARENT = 2;
  123. const SCOPE_TPL_ROOT = 4;
  124. const SCOPE_ROOT = 8;
  125. const SCOPE_SMARTY = 16;
  126. const SCOPE_GLOBAL = 32;
  127. /**
  128. * define caching modes
  129. */
  130. const CACHING_OFF = 0;
  131. const CACHING_LIFETIME_CURRENT = 1;
  132. const CACHING_LIFETIME_SAVED = 2;
  133. /**
  134. * define constant for clearing cache files be saved expiration dates
  135. */
  136. const CLEAR_EXPIRED = - 1;
  137. /**
  138. * define compile check modes
  139. */
  140. const COMPILECHECK_OFF = 0;
  141. const COMPILECHECK_ON = 1;
  142. const COMPILECHECK_CACHEMISS = 2;
  143. /**
  144. * define debug modes
  145. */
  146. const DEBUG_OFF = 0;
  147. const DEBUG_ON = 1;
  148. const DEBUG_INDIVIDUAL = 2;
  149. /**
  150. * modes for handling of "<?php ... ?>" tags in templates.
  151. */
  152. const PHP_PASSTHRU = 0; //-> print tags as plain text
  153. const PHP_QUOTE = 1; //-> escape tags as entities
  154. const PHP_REMOVE = 2; //-> escape tags as entities
  155. const PHP_ALLOW = 3; //-> escape tags as entities
  156. /**
  157. * filter types
  158. */
  159. const FILTER_POST = 'post';
  160. const FILTER_PRE = 'pre';
  161. const FILTER_OUTPUT = 'output';
  162. const FILTER_VARIABLE = 'variable';
  163. /**
  164. * plugin types
  165. */
  166. const PLUGIN_FUNCTION = 'function';
  167. const PLUGIN_BLOCK = 'block';
  168. const PLUGIN_COMPILER = 'compiler';
  169. const PLUGIN_MODIFIER = 'modifier';
  170. const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler';
  171. /**
  172. * Resource caching modes
  173. * (not used since 3.1.30)
  174. */
  175. const RESOURCE_CACHE_OFF = 0;
  176. const RESOURCE_CACHE_AUTOMATIC = 1; // cache template objects by rules
  177. const RESOURCE_CACHE_TEMPLATE = 2; // cache all template objects
  178. const RESOURCE_CACHE_ON = 4; // cache source and compiled resources
  179. /**#@-*/
  180. /**
  181. * assigned global tpl vars
  182. */
  183. public static $global_tpl_vars = array();
  184. /**
  185. * error handler returned by set_error_handler() in Smarty::muteExpectedErrors()
  186. */
  187. public static $_previous_error_handler = null;
  188. /**
  189. * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors()
  190. */
  191. public static $_muted_directories = array();
  192. /**
  193. * Flag denoting if Multibyte String functions are available
  194. */
  195. public static $_MBSTRING = SMARTY_MBSTRING;
  196. /**
  197. * The character set to adhere to (e.g. "UTF-8")
  198. */
  199. public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET;
  200. /**
  201. * The date format to be used internally
  202. * (accepts date() and strftime())
  203. */
  204. public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT;
  205. /**
  206. * Flag denoting if PCRE should run in UTF-8 mode
  207. */
  208. public static $_UTF8_MODIFIER = 'u';
  209. /**
  210. * Flag denoting if operating system is windows
  211. */
  212. public static $_IS_WINDOWS = false;
  213. /**#@+
  214. * variables
  215. */
  216. /**
  217. * auto literal on delimiters with whitespace
  218. *
  219. * @var boolean
  220. */
  221. public $auto_literal = true;
  222. /**
  223. * display error on not assigned variables
  224. *
  225. * @var boolean
  226. */
  227. public $error_unassigned = false;
  228. /**
  229. * look up relative file path in include_path
  230. *
  231. * @var boolean
  232. */
  233. public $use_include_path = false;
  234. /**
  235. * template directory
  236. *
  237. * @var array
  238. */
  239. protected $template_dir = array('./templates/');
  240. /**
  241. * flags for normalized template directory entries
  242. *
  243. * @var array
  244. */
  245. protected $_processedTemplateDir = array();
  246. /**
  247. * flag if template_dir is normalized
  248. *
  249. * @var bool
  250. */
  251. public $_templateDirNormalized = false;
  252. /**
  253. * joined template directory string used in cache keys
  254. *
  255. * @var string
  256. */
  257. public $_joined_template_dir = null;
  258. /**
  259. * config directory
  260. *
  261. * @var array
  262. */
  263. protected $config_dir = array('./configs/');
  264. /**
  265. * flags for normalized template directory entries
  266. *
  267. * @var array
  268. */
  269. protected $_processedConfigDir = array();
  270. /**
  271. * flag if config_dir is normalized
  272. *
  273. * @var bool
  274. */
  275. public $_configDirNormalized = false;
  276. /**
  277. * joined config directory string used in cache keys
  278. *
  279. * @var string
  280. */
  281. public $_joined_config_dir = null;
  282. /**
  283. * default template handler
  284. *
  285. * @var callable
  286. */
  287. public $default_template_handler_func = null;
  288. /**
  289. * default config handler
  290. *
  291. * @var callable
  292. */
  293. public $default_config_handler_func = null;
  294. /**
  295. * default plugin handler
  296. *
  297. * @var callable
  298. */
  299. public $default_plugin_handler_func = null;
  300. /**
  301. * compile directory
  302. *
  303. * @var string
  304. */
  305. protected $compile_dir = './templates_c/';
  306. /**
  307. * flag if template_dir is normalized
  308. *
  309. * @var bool
  310. */
  311. public $_compileDirNormalized = false;
  312. /**
  313. * plugins directory
  314. *
  315. * @var array
  316. */
  317. protected $plugins_dir = array();
  318. /**
  319. * flag if plugins_dir is normalized
  320. *
  321. * @var bool
  322. */
  323. public $_pluginsDirNormalized = false;
  324. /**
  325. * cache directory
  326. *
  327. * @var string
  328. */
  329. protected $cache_dir = './cache/';
  330. /**
  331. * flag if template_dir is normalized
  332. *
  333. * @var bool
  334. */
  335. public $_cacheDirNormalized = false;
  336. /**
  337. * force template compiling?
  338. *
  339. * @var boolean
  340. */
  341. public $force_compile = false;
  342. /**
  343. * check template for modifications?
  344. *
  345. * @var boolean
  346. */
  347. public $compile_check = true;
  348. /**
  349. * use sub dirs for compiled/cached files?
  350. *
  351. * @var boolean
  352. */
  353. public $use_sub_dirs = false;
  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. * merge compiled includes
  362. *
  363. * @var boolean
  364. */
  365. public $merge_compiled_includes = false;
  366. /**
  367. * force cache file creation
  368. *
  369. * @var boolean
  370. */
  371. public $force_cache = false;
  372. /**
  373. * template left-delimiter
  374. *
  375. * @var string
  376. */
  377. public $left_delimiter = "{";
  378. /**
  379. * template right-delimiter
  380. *
  381. * @var string
  382. */
  383. public $right_delimiter = "}";
  384. /**#@+
  385. * security
  386. */
  387. /**
  388. * class name
  389. * This should be instance of Smarty_Security.
  390. *
  391. * @var string
  392. * @see Smarty_Security
  393. */
  394. public $security_class = 'Smarty_Security';
  395. /**
  396. * implementation of security class
  397. *
  398. * @var Smarty_Security
  399. */
  400. public $security_policy = null;
  401. /**
  402. * controls handling of PHP-blocks
  403. *
  404. * @var integer
  405. */
  406. public $php_handling = self::PHP_PASSTHRU;
  407. /**
  408. * controls if the php template file resource is allowed
  409. *
  410. * @var bool
  411. */
  412. public $allow_php_templates = false;
  413. /**#@-*/
  414. /**
  415. * debug mode
  416. * Setting this to true enables the debug-console.
  417. *
  418. * @var boolean
  419. */
  420. public $debugging = false;
  421. /**
  422. * This determines if debugging is enable-able from the browser.
  423. * <ul>
  424. * <li>NONE => no debugging control allowed</li>
  425. * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
  426. * </ul>
  427. *
  428. * @var string
  429. */
  430. public $debugging_ctrl = 'NONE';
  431. /**
  432. * Name of debugging URL-param.
  433. * Only used when $debugging_ctrl is set to 'URL'.
  434. * The name of the URL-parameter that activates debugging.
  435. *
  436. * @var string
  437. */
  438. public $smarty_debug_id = 'SMARTY_DEBUG';
  439. /**
  440. * Path of debug template.
  441. *
  442. * @var string
  443. */
  444. public $debug_tpl = null;
  445. /**
  446. * When set, smarty uses this value as error_reporting-level.
  447. *
  448. * @var int
  449. */
  450. public $error_reporting = null;
  451. /**#@+
  452. * config var settings
  453. */
  454. /**
  455. * Controls whether variables with the same name overwrite each other.
  456. *
  457. * @var boolean
  458. */
  459. public $config_overwrite = true;
  460. /**
  461. * Controls whether config values of on/true/yes and off/false/no get converted to boolean.
  462. *
  463. * @var boolean
  464. */
  465. public $config_booleanize = true;
  466. /**
  467. * Controls whether hidden config sections/vars are read from the file.
  468. *
  469. * @var boolean
  470. */
  471. public $config_read_hidden = false;
  472. /**#@-*/
  473. /**#@+
  474. * resource locking
  475. */
  476. /**
  477. * locking concurrent compiles
  478. *
  479. * @var boolean
  480. */
  481. public $compile_locking = true;
  482. /**
  483. * Controls whether cache resources should use locking mechanism
  484. *
  485. * @var boolean
  486. */
  487. public $cache_locking = false;
  488. /**
  489. * seconds to wait for acquiring a lock before ignoring the write lock
  490. *
  491. * @var float
  492. */
  493. public $locking_timeout = 10;
  494. /**#@-*/
  495. /**
  496. * resource type used if none given
  497. * Must be an valid key of $registered_resources.
  498. *
  499. * @var string
  500. */
  501. public $default_resource_type = 'file';
  502. /**
  503. * caching type
  504. * Must be an element of $cache_resource_types.
  505. *
  506. * @var string
  507. */
  508. public $caching_type = 'file';
  509. /**
  510. * config type
  511. *
  512. * @var string
  513. */
  514. public $default_config_type = 'file';
  515. /**
  516. * check If-Modified-Since headers
  517. *
  518. * @var boolean
  519. */
  520. public $cache_modified_check = false;
  521. /**
  522. * registered plugins
  523. *
  524. * @var array
  525. */
  526. public $registered_plugins = array();
  527. /**
  528. * registered objects
  529. *
  530. * @var array
  531. */
  532. public $registered_objects = array();
  533. /**
  534. * registered classes
  535. *
  536. * @var array
  537. */
  538. public $registered_classes = array();
  539. /**
  540. * registered filters
  541. *
  542. * @var array
  543. */
  544. public $registered_filters = array();
  545. /**
  546. * registered resources
  547. *
  548. * @var array
  549. */
  550. public $registered_resources = array();
  551. /**
  552. * registered cache resources
  553. *
  554. * @var array
  555. */
  556. public $registered_cache_resources = array();
  557. /**
  558. * autoload filter
  559. *
  560. * @var array
  561. */
  562. public $autoload_filters = array();
  563. /**
  564. * default modifier
  565. *
  566. * @var array
  567. */
  568. public $default_modifiers = array();
  569. /**
  570. * autoescape variable output
  571. *
  572. * @var boolean
  573. */
  574. public $escape_html = false;
  575. /**
  576. * start time for execution time calculation
  577. *
  578. * @var int
  579. */
  580. public $start_time = 0;
  581. /**
  582. * required by the compiler for BC
  583. *
  584. * @var string
  585. */
  586. public $_current_file = null;
  587. /**
  588. * internal flag to enable parser debugging
  589. *
  590. * @var bool
  591. */
  592. public $_parserdebug = false;
  593. /**
  594. * This object type (Smarty = 1, template = 2, data = 4)
  595. *
  596. * @var int
  597. */
  598. public $_objType = 1;
  599. /**
  600. * Debug object
  601. *
  602. * @var Smarty_Internal_Debug
  603. */
  604. public $_debug = null;
  605. /**
  606. * removed properties
  607. *
  608. * @var string[]
  609. */
  610. private $obsoleteProperties = array('resource_caching', 'template_resource_caching', 'direct_access_security',
  611. '_dir_perms', '_file_perms', 'plugin_search_order',
  612. 'inheritance_merge_compiled_includes', 'resource_cache_mode',);
  613. /**
  614. * List of private properties which will call getter/setter on a direct access
  615. *
  616. * @var string[]
  617. */
  618. private $accessMap = array('template_dir' => 'TemplateDir', 'config_dir' => 'ConfigDir',
  619. 'plugins_dir' => 'PluginsDir', 'compile_dir' => 'CompileDir',
  620. 'cache_dir' => 'CacheDir',);
  621. /**#@-*/
  622. /**
  623. * Initialize new Smarty object
  624. */
  625. public function __construct()
  626. {
  627. parent::__construct();
  628. if (is_callable('mb_internal_encoding')) {
  629. mb_internal_encoding(Smarty::$_CHARSET);
  630. }
  631. $this->start_time = microtime(true);
  632. if (isset($_SERVER[ 'SCRIPT_NAME' ])) {
  633. Smarty::$global_tpl_vars[ 'SCRIPT_NAME' ] = new Smarty_Variable($_SERVER[ 'SCRIPT_NAME' ]);
  634. }
  635. // Check if we're running on windows
  636. Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
  637. // let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8
  638. if (Smarty::$_CHARSET !== 'UTF-8') {
  639. Smarty::$_UTF8_MODIFIER = '';
  640. }
  641. }
  642. /**
  643. * Check if a template resource exists
  644. *
  645. * @param string $resource_name template name
  646. *
  647. * @return boolean status
  648. */
  649. public function templateExists($resource_name)
  650. {
  651. // create source object
  652. $source = Smarty_Template_Source::load(null, $this, $resource_name);
  653. return $source->exists;
  654. }
  655. /**
  656. * Loads security class and enables security
  657. *
  658. * @param string|Smarty_Security $security_class if a string is used, it must be class-name
  659. *
  660. * @return Smarty current Smarty instance for chaining
  661. * @throws SmartyException when an invalid class name is provided
  662. */
  663. public function enableSecurity($security_class = null)
  664. {
  665. Smarty_Security::enableSecurity($this, $security_class);
  666. return $this;
  667. }
  668. /**
  669. * Disable security
  670. *
  671. * @return Smarty current Smarty instance for chaining
  672. */
  673. public function disableSecurity()
  674. {
  675. $this->security_policy = null;
  676. return $this;
  677. }
  678. /**
  679. * Set template directory
  680. *
  681. * @param string|array $template_dir directory(s) of template sources
  682. * @param bool $isConfig true for config_dir
  683. *
  684. * @return \Smarty current Smarty instance for chaining
  685. */
  686. public function setTemplateDir($template_dir, $isConfig = false)
  687. {
  688. if ($isConfig) {
  689. $this->config_dir = array();
  690. $this->_processedConfigDir = array();
  691. } else {
  692. $this->template_dir = array();
  693. $this->_processedTemplateDir = array();
  694. }
  695. $this->addTemplateDir($template_dir, null, $isConfig);
  696. return $this;
  697. }
  698. /**
  699. * Add template directory(s)
  700. *
  701. * @param string|array $template_dir directory(s) of template sources
  702. * @param string $key of the array element to assign the template dir to
  703. * @param bool $isConfig true for config_dir
  704. *
  705. * @return Smarty current Smarty instance for chaining
  706. */
  707. public function addTemplateDir($template_dir, $key = null, $isConfig = false)
  708. {
  709. if ($isConfig) {
  710. $processed = &$this->_processedConfigDir;
  711. $dir = &$this->config_dir;
  712. $this->_configDirNormalized = false;
  713. } else {
  714. $processed = &$this->_processedTemplateDir;
  715. $dir = &$this->template_dir;
  716. $this->_templateDirNormalized = false;
  717. }
  718. if (is_array($template_dir)) {
  719. foreach ($template_dir as $k => $v) {
  720. if (is_int($k)) {
  721. // indexes are not merged but appended
  722. $dir[] = $v;
  723. } else {
  724. // string indexes are overridden
  725. $dir[ $k ] = $v;
  726. unset($processed[ $key ]);
  727. }
  728. }
  729. } else {
  730. if ($key !== null) {
  731. // override directory at specified index
  732. $dir[ $key ] = $template_dir;
  733. unset($processed[ $key ]);
  734. } else {
  735. // append new directory
  736. $dir[] = $template_dir;
  737. }
  738. }
  739. return $this;
  740. }
  741. /**
  742. * Get template directories
  743. *
  744. * @param mixed $index index of directory to get, null to get all
  745. * @param bool $isConfig true for config_dir
  746. *
  747. * @return array list of template directories, or directory of $index
  748. */
  749. public function getTemplateDir($index = null, $isConfig = false)
  750. {
  751. if ($isConfig) {
  752. $dir = &$this->config_dir;
  753. } else {
  754. $dir = &$this->template_dir;
  755. }
  756. if ($isConfig ? !$this->_configDirNormalized : !$this->_templateDirNormalized) {
  757. $this->_nomalizeTemplateConfig($isConfig);
  758. }
  759. if ($index !== null) {
  760. return isset($dir[ $index ]) ? $dir[ $index ] : null;
  761. }
  762. return $dir;
  763. }
  764. /**
  765. * Set config directory
  766. *
  767. * @param $config_dir
  768. *
  769. * @return Smarty current Smarty instance for chaining
  770. */
  771. public function setConfigDir($config_dir)
  772. {
  773. return $this->setTemplateDir($config_dir, true);
  774. }
  775. /**
  776. * Add config directory(s)
  777. *
  778. * @param string|array $config_dir directory(s) of config sources
  779. * @param mixed $key key of the array element to assign the config dir to
  780. *
  781. * @return Smarty current Smarty instance for chaining
  782. */
  783. public function addConfigDir($config_dir, $key = null)
  784. {
  785. return $this->addTemplateDir($config_dir, $key, true);
  786. }
  787. /**
  788. * Get config directory
  789. *
  790. * @param mixed $index index of directory to get, null to get all
  791. *
  792. * @return array configuration directory
  793. */
  794. public function getConfigDir($index = null)
  795. {
  796. return $this->getTemplateDir($index, true);
  797. }
  798. /**
  799. * Set plugins directory
  800. *
  801. * @param string|array $plugins_dir directory(s) of plugins
  802. *
  803. * @return Smarty current Smarty instance for chaining
  804. */
  805. public function setPluginsDir($plugins_dir)
  806. {
  807. $this->plugins_dir = (array) $plugins_dir;
  808. $this->_pluginsDirNormalized = false;
  809. return $this;
  810. }
  811. /**
  812. * Adds directory of plugin files
  813. *
  814. * @param null|array $plugins_dir
  815. *
  816. * @return Smarty current Smarty instance for chaining
  817. */
  818. public function addPluginsDir($plugins_dir)
  819. {
  820. if (empty($this->plugins_dir)) {
  821. $this->plugins_dir[] = SMARTY_PLUGINS_DIR;
  822. }
  823. $this->plugins_dir = array_merge($this->plugins_dir, (array) $plugins_dir);
  824. $this->_pluginsDirNormalized = false;
  825. return $this;
  826. }
  827. /**
  828. * Get plugin directories
  829. *
  830. * @return array list of plugin directories
  831. */
  832. public function getPluginsDir()
  833. {
  834. if (empty($this->plugins_dir)) {
  835. $this->plugins_dir[] = SMARTY_PLUGINS_DIR;
  836. $this->_pluginsDirNormalized = false;
  837. }
  838. if (!$this->_pluginsDirNormalized) {
  839. if (!is_array($this->plugins_dir)) {
  840. $this->plugins_dir = (array) $this->plugins_dir;
  841. }
  842. foreach ($this->plugins_dir as $k => $v) {
  843. $this->plugins_dir[ $k ] = $this->_realpath(rtrim($v, "/\\") . DS, true);
  844. }
  845. $this->_cache[ 'plugin_files' ] = array();
  846. $this->_pluginsDirNormalized = true;
  847. }
  848. return $this->plugins_dir;
  849. }
  850. /**
  851. *
  852. * @param string $compile_dir directory to store compiled templates in
  853. *
  854. * @return Smarty current Smarty instance for chaining
  855. */
  856. public function setCompileDir($compile_dir)
  857. {
  858. $this->_normalizeDir('compile_dir', $compile_dir);
  859. $this->_compileDirNormalized = true;
  860. return $this;
  861. }
  862. /**
  863. * Get compiled directory
  864. *
  865. * @return string path to compiled templates
  866. */
  867. public function getCompileDir()
  868. {
  869. if (!$this->_compileDirNormalized) {
  870. $this->_normalizeDir('compile_dir', $this->compile_dir);
  871. $this->_compileDirNormalized = true;
  872. }
  873. return $this->compile_dir;
  874. }
  875. /**
  876. * Set cache directory
  877. *
  878. * @param string $cache_dir directory to store cached templates in
  879. *
  880. * @return Smarty current Smarty instance for chaining
  881. */
  882. public function setCacheDir($cache_dir)
  883. {
  884. $this->_normalizeDir('cache_dir', $cache_dir);
  885. $this->_cacheDirNormalized = true;
  886. return $this;
  887. }
  888. /**
  889. * Get cache directory
  890. *
  891. * @return string path of cache directory
  892. */
  893. public function getCacheDir()
  894. {
  895. if (!$this->_cacheDirNormalized) {
  896. $this->_normalizeDir('cache_dir', $this->cache_dir);
  897. $this->_cacheDirNormalized = true;
  898. }
  899. return $this->cache_dir;
  900. }
  901. /**
  902. * Normalize and set directory string
  903. *
  904. * @param string $dirName cache_dir or compile_dir
  905. * @param string $dir filepath of folder
  906. */
  907. private function _normalizeDir($dirName, $dir)
  908. {
  909. $this->{$dirName} = $this->_realpath(rtrim($dir, "/\\") . DS, true);
  910. if (!isset(Smarty::$_muted_directories[ $this->{$dirName} ])) {
  911. Smarty::$_muted_directories[ $this->{$dirName} ] = null;
  912. }
  913. }
  914. /**
  915. * Normalize template_dir or config_dir
  916. *
  917. * @param bool $isConfig true for config_dir
  918. *
  919. */
  920. private function _nomalizeTemplateConfig($isConfig)
  921. {
  922. if ($isConfig) {
  923. $processed = &$this->_processedConfigDir;
  924. $dir = &$this->config_dir;
  925. } else {
  926. $processed = &$this->_processedTemplateDir;
  927. $dir = &$this->template_dir;
  928. }
  929. if (!is_array($dir)) {
  930. $dir = (array) $dir;
  931. }
  932. foreach ($dir as $k => $v) {
  933. if (!isset($processed[ $k ])) {
  934. $dir[ $k ] = $v = $this->_realpath(rtrim($v, "/\\") . DS, true);
  935. $processed[ $k ] = true;
  936. }
  937. }
  938. $isConfig ? $this->_configDirNormalized = true : $this->_templateDirNormalized = true;
  939. $isConfig ? $this->_joined_config_dir = join('#', $this->config_dir) :
  940. $this->_joined_template_dir = join('#', $this->template_dir);
  941. }
  942. /**
  943. * creates a template object
  944. *
  945. * @param string $template the resource handle of the template file
  946. * @param mixed $cache_id cache id to be used with this template
  947. * @param mixed $compile_id compile id to be used with this template
  948. * @param object $parent next higher level of Smarty variables
  949. * @param boolean $do_clone flag is Smarty object shall be cloned
  950. *
  951. * @return object template object
  952. */
  953. public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true)
  954. {
  955. if ($cache_id !== null && (is_object($cache_id) || is_array($cache_id))) {
  956. $parent = $cache_id;
  957. $cache_id = null;
  958. }
  959. if ($parent !== null && is_array($parent)) {
  960. $data = $parent;
  961. $parent = null;
  962. } else {
  963. $data = null;
  964. }
  965. $_templateId = $this->_getTemplateId($template, $cache_id, $compile_id);
  966. $tpl = null;
  967. if ($this->caching && isset($this->_cache[ 'isCached' ][ $_templateId ])) {
  968. $tpl = $do_clone ? clone $this->_cache[ 'isCached' ][ $_templateId ] :
  969. $this->_cache[ 'isCached' ][ $_templateId ];
  970. $tpl->tpl_vars = $tpl->config_vars = array();
  971. } else if (!$do_clone && isset($this->_cache[ 'tplObjects' ][ $_templateId ])) {
  972. $tpl = clone $this->_cache[ 'tplObjects' ][ $_templateId ];
  973. } else {
  974. /* @var Smarty_Internal_Template $tpl */
  975. $tpl = new $this->template_class($template, $this, null, $cache_id, $compile_id, null, null);
  976. $tpl->templateId = $_templateId;
  977. }
  978. if ($do_clone) {
  979. $tpl->smarty = clone $tpl->smarty;
  980. }
  981. $tpl->parent = $parent ? $parent : $this;
  982. // fill data if present
  983. if (!empty($data) && is_array($data)) {
  984. // set up variable values
  985. foreach ($data as $_key => $_val) {
  986. $tpl->tpl_vars[ $_key ] = new Smarty_Variable($_val);
  987. }
  988. }
  989. if ($this->debugging || $this->debugging_ctrl == 'URL') {
  990. $tpl->smarty->_debug = new Smarty_Internal_Debug();
  991. // check URL debugging control
  992. if (!$this->debugging && $this->debugging_ctrl == 'URL') {
  993. $tpl->smarty->_debug->debugUrl($tpl->smarty);
  994. }
  995. }
  996. return $tpl;
  997. }
  998. /**
  999. * Takes unknown classes and loads plugin files for them
  1000. * class name format: Smarty_PluginType_PluginName
  1001. * plugin filename format: plugintype.pluginname.php
  1002. *
  1003. * @param string $plugin_name class plugin name to load
  1004. * @param bool $check check if already loaded
  1005. *
  1006. * @throws SmartyException
  1007. * @return string |boolean filepath of loaded file or false
  1008. */
  1009. public function loadPlugin($plugin_name, $check = true)
  1010. {
  1011. return $this->ext->loadPlugin->loadPlugin($this, $plugin_name, $check);
  1012. }
  1013. /**
  1014. * Get unique template id
  1015. *
  1016. * @param string $template_name
  1017. * @param null|mixed $cache_id
  1018. * @param null|mixed $compile_id
  1019. * @param null $caching
  1020. * @param \Smarty_Internal_Template $template
  1021. *
  1022. * @return string
  1023. */
  1024. public function _getTemplateId($template_name, $cache_id = null, $compile_id = null, $caching = null,
  1025. Smarty_Internal_Template $template = null)
  1026. {
  1027. $template_name = (strpos($template_name, ':') === false) ? "{$this->default_resource_type}:{$template_name}" :
  1028. $template_name;
  1029. $cache_id = $cache_id === null ? $this->cache_id : $cache_id;
  1030. $compile_id = $compile_id === null ? $this->compile_id : $compile_id;
  1031. $caching = (int) ($caching === null ? $this->caching : $caching);
  1032. if ((isset($template) && strpos($template_name, ':.') !== false) || $this->allow_ambiguous_resources) {
  1033. $_templateId =
  1034. Smarty_Resource::getUniqueTemplateName((isset($template) ? $template : $this), $template_name) .
  1035. "#{$cache_id}#{$compile_id}#{$caching}";
  1036. } else {
  1037. $_templateId = $this->_joined_template_dir . "#{$template_name}#{$cache_id}#{$compile_id}#{$caching}";
  1038. }
  1039. if (isset($_templateId[ 150 ])) {
  1040. $_templateId = sha1($_templateId);
  1041. }
  1042. return $_templateId;
  1043. }
  1044. /**
  1045. * Normalize path
  1046. * - remove /./ and /../
  1047. * - make it absolute if required
  1048. *
  1049. * @param string $path file path
  1050. * @param bool $realpath if true - convert to absolute
  1051. * false - convert to relative
  1052. * null - keep as it is but remove /./ /../
  1053. *
  1054. * @return string
  1055. */
  1056. public function _realpath($path, $realpath = null)
  1057. {
  1058. $nds = DS == '/' ? '\\' : '/';
  1059. // normalize DS
  1060. $path = str_replace($nds, DS, $path);
  1061. preg_match('%^(?<root>(?:[[:alpha:]]:[\\\\]|/|[\\\\]{2}[[:alpha:]]+|[[:print:]]{2,}:[/]{2}|[\\\\])?)(?<path>(?:[[:print:]]*))$%',
  1062. $path, $parts);
  1063. $path = $parts[ 'path' ];
  1064. if ($parts[ 'root' ] == '\\') {
  1065. $parts[ 'root' ] = substr(getcwd(), 0, 2) . $parts[ 'root' ];
  1066. } else {
  1067. if ($realpath !== null && !$parts[ 'root' ]) {
  1068. $path = getcwd() . DS . $path;
  1069. }
  1070. }
  1071. // remove noop 'DS DS' and 'DS.DS' patterns
  1072. $path = preg_replace('#([\\\\/]([.]?[\\\\/])+)#', DS, $path);
  1073. // resolve '..DS' pattern, smallest first
  1074. if (strpos($path, '..' . DS) != false &&
  1075. preg_match_all('#(([.]?[\\\\/])*([.][.])[\\\\/]([.]?[\\\\/])*)+#', $path, $match)
  1076. ) {
  1077. $counts = array();
  1078. foreach ($match[ 0 ] as $m) {
  1079. $counts[] = (int) ((strlen($m) - 1) / 3);
  1080. }
  1081. sort($counts);
  1082. foreach ($counts as $count) {
  1083. $path = preg_replace('#(([\\\\/]([.]?[\\\\/])*[^\\\\/.]+){' . $count .
  1084. '}[\\\\/]([.]?[\\\\/])*([.][.][\\\\/]([.]?[\\\\/])*){' . $count . '})(?=[^.])#',
  1085. DS, $path);
  1086. }
  1087. }
  1088. return $parts[ 'root' ] . $path;
  1089. }
  1090. /**
  1091. * Empty template objects cache
  1092. */
  1093. public function _clearTemplateCache()
  1094. {
  1095. $this->_cache[ 'isCached' ] = array();
  1096. $this->_cache[ 'tplObjects' ] = array();
  1097. }
  1098. /**
  1099. * @param boolean $compile_check
  1100. */
  1101. public function setCompileCheck($compile_check)
  1102. {
  1103. $this->compile_check = $compile_check;
  1104. }
  1105. /**
  1106. * @param boolean $use_sub_dirs
  1107. */
  1108. public function setUseSubDirs($use_sub_dirs)
  1109. {
  1110. $this->use_sub_dirs = $use_sub_dirs;
  1111. }
  1112. /**
  1113. * @param int $error_reporting
  1114. */
  1115. public function setErrorReporting($error_reporting)
  1116. {
  1117. $this->error_reporting = $error_reporting;
  1118. }
  1119. /**
  1120. * @param boolean $escape_html
  1121. */
  1122. public function setEscapeHtml($escape_html)
  1123. {
  1124. $this->escape_html = $escape_html;
  1125. }
  1126. /**
  1127. * @param boolean $auto_literal
  1128. */
  1129. public function setAutoLiteral($auto_literal)
  1130. {
  1131. $this->auto_literal = $auto_literal;
  1132. }
  1133. /**
  1134. * @param boolean $force_compile
  1135. */
  1136. public function setForceCompile($force_compile)
  1137. {
  1138. $this->force_compile = $force_compile;
  1139. }
  1140. /**
  1141. * @param boolean $merge_compiled_includes
  1142. */
  1143. public function setMergeCompiledIncludes($merge_compiled_includes)
  1144. {
  1145. $this->merge_compiled_includes = $merge_compiled_includes;
  1146. }
  1147. /**
  1148. * @param string $left_delimiter
  1149. */
  1150. public function setLeftDelimiter($left_delimiter)
  1151. {
  1152. $this->left_delimiter = $left_delimiter;
  1153. }
  1154. /**
  1155. * @param string $right_delimiter
  1156. */
  1157. public function setRightDelimiter($right_delimiter)
  1158. {
  1159. $this->right_delimiter = $right_delimiter;
  1160. }
  1161. /**
  1162. * @param boolean $debugging
  1163. */
  1164. public function setDebugging($debugging)
  1165. {
  1166. $this->debugging = $debugging;
  1167. }
  1168. /**
  1169. * @param boolean $config_overwrite
  1170. */
  1171. public function setConfigOverwrite($config_overwrite)
  1172. {
  1173. $this->config_overwrite = $config_overwrite;
  1174. }
  1175. /**
  1176. * @param boolean $config_booleanize
  1177. */
  1178. public function setConfigBooleanize($config_booleanize)
  1179. {
  1180. $this->config_booleanize = $config_booleanize;
  1181. }
  1182. /**
  1183. * @param boolean $config_read_hidden
  1184. */
  1185. public function setConfigReadHidden($config_read_hidden)
  1186. {
  1187. $this->config_read_hidden = $config_read_hidden;
  1188. }
  1189. /**
  1190. * @param boolean $compile_locking
  1191. */
  1192. public function setCompileLocking($compile_locking)
  1193. {
  1194. $this->compile_locking = $compile_locking;
  1195. }
  1196. /**
  1197. * @param string $default_resource_type
  1198. */
  1199. public function setDefaultResourceType($default_resource_type)
  1200. {
  1201. $this->default_resource_type = $default_resource_type;
  1202. }
  1203. /**
  1204. * @param string $caching_type
  1205. */
  1206. public function setCachingType($caching_type)
  1207. {
  1208. $this->caching_type = $caching_type;
  1209. }
  1210. /**
  1211. * Test install
  1212. *
  1213. * @param null $errors
  1214. */
  1215. public function testInstall(&$errors = null)
  1216. {
  1217. Smarty_Internal_TestInstall::testInstall($this, $errors);
  1218. }
  1219. /**
  1220. * <<magic>> Generic getter.
  1221. * Calls the appropriate getter function.
  1222. * Issues an E_USER_NOTICE if no valid getter is found.
  1223. *
  1224. * @param string $name property name
  1225. *
  1226. * @return mixed
  1227. */
  1228. public function __get($name)
  1229. {
  1230. if (isset($this->accessMap[ $name ])) {
  1231. $method = 'get' . $this->accessMap[ $name ];
  1232. return $this->{$method}();
  1233. } elseif (isset($this->_cache[ $name ])) {
  1234. return $this->_cache[ $name ];
  1235. } elseif (in_array($name, $this->obsoleteProperties)) {
  1236. return null;
  1237. } else {
  1238. trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
  1239. }
  1240. return null;
  1241. }
  1242. /**
  1243. * <<magic>> Generic setter.
  1244. * Calls the appropriate setter function.
  1245. * Issues an E_USER_NOTICE if no valid setter is found.
  1246. *
  1247. * @param string $name property name
  1248. * @param mixed $value parameter passed to setter
  1249. */
  1250. public function __set($name, $value)
  1251. {
  1252. if (isset($this->accessMap[ $name ])) {
  1253. $method = 'set' . $this->accessMap[ $name ];
  1254. $this->{$method}($value);
  1255. } elseif (in_array($name, $this->obsoleteProperties)) {
  1256. return;
  1257. } else {
  1258. if (is_object($value) && method_exists($value, $name)) {
  1259. $this->$name = $value;
  1260. } else {
  1261. trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
  1262. }
  1263. }
  1264. }
  1265. /**
  1266. * Error Handler to mute expected messages
  1267. *
  1268. * @link http://php.net/set_error_handler
  1269. *
  1270. * @param integer $errno Error level
  1271. * @param $errstr
  1272. * @param $errfile
  1273. * @param $errline
  1274. * @param $errcontext
  1275. *
  1276. * @return bool|void
  1277. */
  1278. public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext)
  1279. {
  1280. $_is_muted_directory = false;
  1281. // add the SMARTY_DIR to the list of muted directories
  1282. if (!isset(Smarty::$_muted_directories[ SMARTY_DIR ])) {
  1283. $smarty_dir = realpath(SMARTY_DIR);
  1284. if ($smarty_dir !== false) {
  1285. Smarty::$_muted_directories[ SMARTY_DIR ] =
  1286. array('file' => $smarty_dir, 'length' => strlen($smarty_dir),);
  1287. }
  1288. }
  1289. // walk the muted directories and test against $errfile
  1290. foreach (Smarty::$_muted_directories as $key => &$dir) {
  1291. if (!$dir) {
  1292. // resolve directory and length for speedy comparisons
  1293. $file = realpath($key);
  1294. if ($file === false) {
  1295. // this directory does not exist, remove and skip it
  1296. unset(Smarty::$_muted_directories[ $key ]);
  1297. continue;
  1298. }
  1299. $dir = array('file' => $file, 'length' => strlen($file),);
  1300. }
  1301. if (!strncmp($errfile, $dir[ 'file' ], $dir[ 'length' ])) {
  1302. $_is_muted_directory = true;
  1303. break;
  1304. }
  1305. }
  1306. // pass to next error handler if this error did not occur inside SMARTY_DIR
  1307. // or the error was within smarty but masked to be ignored
  1308. if (!$_is_muted_directory || ($errno && $errno & error_reporting())) {
  1309. if (Smarty::$_previous_error_handler) {
  1310. return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline,
  1311. $errcontext);
  1312. } else {
  1313. return false;
  1314. }
  1315. }
  1316. return;
  1317. }
  1318. /**
  1319. * Enable error handler to mute expected messages
  1320. *
  1321. * @return void
  1322. */
  1323. public static function muteExpectedErrors()
  1324. {
  1325. /*
  1326. error muting is done because some people implemented custom error_handlers using
  1327. http://php.net/set_error_handler and for some reason did not understand the following paragraph:
  1328. It is important to remember that the standard PHP error handler is completely bypassed for the
  1329. error types specified by error_types unless the callback function returns FALSE.
  1330. error_reporting() settings will have no effect and your error handler will be called regardless -
  1331. however you are still able to read the current value of error_reporting and act appropriately.
  1332. Of particular note is that this value will be 0 if the statement that caused the error was
  1333. prepended by the @ error-control operator.
  1334. Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include
  1335. - @filemtime() is almost twice as fast as using an additional file_exists()
  1336. - between file_exists() and filemtime() a possible race condition is opened,
  1337. which does not exist using the simple @filemtime() approach.
  1338. */
  1339. $error_handler = array('Smarty', 'mutingErrorHandler');
  1340. $previous = set_error_handler($error_handler);
  1341. // avoid dead loops
  1342. if ($previous !== $error_handler) {
  1343. Smarty::$_previous_error_handler = $previous;
  1344. }
  1345. }
  1346. /**
  1347. * Disable error handler muting expected messages
  1348. *
  1349. * @return void
  1350. */
  1351. public static function unmuteExpectedErrors()
  1352. {
  1353. restore_error_handler();
  1354. }
  1355. }