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