Total Complexity | 249 |
Total Lines | 2184 |
Duplicated Lines | 0 % |
Changes | 1 | ||
Bugs | 0 | Features | 0 |
Complex classes like Smarty often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Smarty, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
52 | class Smarty extends \Smarty\TemplateBase { |
||
53 | |||
54 | /** |
||
55 | * smarty version |
||
56 | */ |
||
57 | const SMARTY_VERSION = '5.4.3'; |
||
58 | |||
59 | /** |
||
60 | * define caching modes |
||
61 | */ |
||
62 | const CACHING_OFF = 0; |
||
63 | const CACHING_LIFETIME_CURRENT = 1; |
||
64 | const CACHING_LIFETIME_SAVED = 2; |
||
65 | /** |
||
66 | * define constant for clearing cache files be saved expiration dates |
||
67 | */ |
||
68 | const CLEAR_EXPIRED = -1; |
||
69 | /** |
||
70 | * define compile check modes |
||
71 | */ |
||
72 | const COMPILECHECK_OFF = 0; |
||
73 | const COMPILECHECK_ON = 1; |
||
74 | /** |
||
75 | * filter types |
||
76 | */ |
||
77 | const FILTER_POST = 'post'; |
||
78 | const FILTER_PRE = 'pre'; |
||
79 | const FILTER_OUTPUT = 'output'; |
||
80 | const FILTER_VARIABLE = 'variable'; |
||
81 | /** |
||
82 | * plugin types |
||
83 | */ |
||
84 | const PLUGIN_FUNCTION = 'function'; |
||
85 | const PLUGIN_BLOCK = 'block'; |
||
86 | const PLUGIN_COMPILER = 'compiler'; |
||
87 | const PLUGIN_MODIFIER = 'modifier'; |
||
88 | const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler'; |
||
89 | |||
90 | /** |
||
91 | * The character set to adhere to (defaults to "UTF-8") |
||
92 | */ |
||
93 | public static $_CHARSET = 'UTF-8'; |
||
94 | |||
95 | /** |
||
96 | * The date format to be used internally |
||
97 | * (accepts date() and strftime()) |
||
98 | */ |
||
99 | public static $_DATE_FORMAT = '%b %e, %Y'; |
||
100 | |||
101 | /** |
||
102 | * Flag denoting if PCRE should run in UTF-8 mode |
||
103 | */ |
||
104 | public static $_UTF8_MODIFIER = 'u'; |
||
105 | |||
106 | /** |
||
107 | * Flag denoting if operating system is windows |
||
108 | */ |
||
109 | public static $_IS_WINDOWS = false; |
||
110 | |||
111 | /** |
||
112 | * auto literal on delimiters with whitespace |
||
113 | * |
||
114 | * @var boolean |
||
115 | */ |
||
116 | public $auto_literal = true; |
||
117 | |||
118 | /** |
||
119 | * display error on not assigned variables |
||
120 | * |
||
121 | * @var boolean |
||
122 | */ |
||
123 | public $error_unassigned = false; |
||
124 | |||
125 | /** |
||
126 | * flag if template_dir is normalized |
||
127 | * |
||
128 | * @var bool |
||
129 | */ |
||
130 | public $_templateDirNormalized = false; |
||
131 | |||
132 | /** |
||
133 | * joined template directory string used in cache keys |
||
134 | * |
||
135 | * @var string |
||
136 | */ |
||
137 | public $_joined_template_dir = null; |
||
138 | |||
139 | /** |
||
140 | * flag if config_dir is normalized |
||
141 | * |
||
142 | * @var bool |
||
143 | */ |
||
144 | public $_configDirNormalized = false; |
||
145 | |||
146 | /** |
||
147 | * joined config directory string used in cache keys |
||
148 | * |
||
149 | * @var string |
||
150 | */ |
||
151 | public $_joined_config_dir = null; |
||
152 | |||
153 | /** |
||
154 | * default template handler |
||
155 | * |
||
156 | * @var callable |
||
157 | */ |
||
158 | public $default_template_handler_func = null; |
||
159 | |||
160 | /** |
||
161 | * default config handler |
||
162 | * |
||
163 | * @var callable |
||
164 | */ |
||
165 | public $default_config_handler_func = null; |
||
166 | |||
167 | /** |
||
168 | * default plugin handler |
||
169 | * |
||
170 | * @var callable |
||
171 | */ |
||
172 | private $default_plugin_handler_func = null; |
||
173 | |||
174 | /** |
||
175 | * flag if template_dir is normalized |
||
176 | * |
||
177 | * @var bool |
||
178 | */ |
||
179 | public $_compileDirNormalized = false; |
||
180 | |||
181 | /** |
||
182 | * flag if template_dir is normalized |
||
183 | * |
||
184 | * @var bool |
||
185 | */ |
||
186 | public $_cacheDirNormalized = false; |
||
187 | |||
188 | /** |
||
189 | * force template compiling? |
||
190 | * |
||
191 | * @var boolean |
||
192 | */ |
||
193 | public $force_compile = false; |
||
194 | |||
195 | /** |
||
196 | * use sub dirs for compiled/cached files? |
||
197 | * |
||
198 | * @var boolean |
||
199 | */ |
||
200 | public $use_sub_dirs = false; |
||
201 | |||
202 | /** |
||
203 | * merge compiled includes |
||
204 | * |
||
205 | * @var boolean |
||
206 | */ |
||
207 | public $merge_compiled_includes = false; |
||
208 | |||
209 | /** |
||
210 | * force cache file creation |
||
211 | * |
||
212 | * @var boolean |
||
213 | */ |
||
214 | public $force_cache = false; |
||
215 | |||
216 | /** |
||
217 | * template left-delimiter |
||
218 | * |
||
219 | * @var string |
||
220 | */ |
||
221 | private $left_delimiter = "{"; |
||
222 | |||
223 | /** |
||
224 | * template right-delimiter |
||
225 | * |
||
226 | * @var string |
||
227 | */ |
||
228 | private $right_delimiter = "}"; |
||
229 | |||
230 | /** |
||
231 | * array of strings which shall be treated as literal by compiler |
||
232 | * |
||
233 | * @var array string |
||
234 | */ |
||
235 | public $literals = []; |
||
236 | |||
237 | /** |
||
238 | * class name |
||
239 | * This should be instance of \Smarty\Security. |
||
240 | * |
||
241 | * @var string |
||
242 | * @see \Smarty\Security |
||
243 | */ |
||
244 | public $security_class = \Smarty\Security::class; |
||
245 | |||
246 | /** |
||
247 | * implementation of security class |
||
248 | * |
||
249 | * @var \Smarty\Security |
||
250 | */ |
||
251 | public $security_policy = null; |
||
252 | |||
253 | /** |
||
254 | * debug mode |
||
255 | * Setting this to true enables the debug-console. Setting it to 2 enables individual Debug Console window by |
||
256 | * template name. |
||
257 | * |
||
258 | * @var boolean|int |
||
259 | */ |
||
260 | public $debugging = false; |
||
261 | |||
262 | /** |
||
263 | * This determines if debugging is enable-able from the browser. |
||
264 | * <ul> |
||
265 | * <li>NONE => no debugging control allowed</li> |
||
266 | * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li> |
||
267 | * </ul> |
||
268 | * |
||
269 | * @var string |
||
270 | */ |
||
271 | public $debugging_ctrl = 'NONE'; |
||
272 | |||
273 | /** |
||
274 | * Name of debugging URL-param. |
||
275 | * Only used when $debugging_ctrl is set to 'URL'. |
||
276 | * The name of the URL-parameter that activates debugging. |
||
277 | * |
||
278 | * @var string |
||
279 | */ |
||
280 | public $smarty_debug_id = 'SMARTY_DEBUG'; |
||
281 | |||
282 | /** |
||
283 | * Path of debug template. |
||
284 | * |
||
285 | * @var string |
||
286 | */ |
||
287 | public $debug_tpl = null; |
||
288 | |||
289 | /** |
||
290 | * When set, smarty uses this value as error_reporting-level. |
||
291 | * |
||
292 | * @var int |
||
293 | */ |
||
294 | public $error_reporting = null; |
||
295 | |||
296 | /** |
||
297 | * Controls whether variables with the same name overwrite each other. |
||
298 | * |
||
299 | * @var boolean |
||
300 | */ |
||
301 | public $config_overwrite = true; |
||
302 | |||
303 | /** |
||
304 | * Controls whether config values of on/true/yes and off/false/no get converted to boolean. |
||
305 | * |
||
306 | * @var boolean |
||
307 | */ |
||
308 | public $config_booleanize = true; |
||
309 | |||
310 | /** |
||
311 | * Controls whether hidden config sections/vars are read from the file. |
||
312 | * |
||
313 | * @var boolean |
||
314 | */ |
||
315 | public $config_read_hidden = false; |
||
316 | |||
317 | /** |
||
318 | * locking concurrent compiles |
||
319 | * |
||
320 | * @var boolean |
||
321 | */ |
||
322 | public $compile_locking = true; |
||
323 | |||
324 | /** |
||
325 | * Controls whether cache resources should use locking mechanism |
||
326 | * |
||
327 | * @var boolean |
||
328 | */ |
||
329 | public $cache_locking = false; |
||
330 | |||
331 | /** |
||
332 | * seconds to wait for acquiring a lock before ignoring the write lock |
||
333 | * |
||
334 | * @var float |
||
335 | */ |
||
336 | public $locking_timeout = 10; |
||
337 | |||
338 | /** |
||
339 | * resource type used if none given |
||
340 | * Must be a valid key of $registered_resources. |
||
341 | * |
||
342 | * @var string |
||
343 | */ |
||
344 | public $default_resource_type = 'file'; |
||
345 | |||
346 | /** |
||
347 | * cache resource |
||
348 | * Must be a subclass of \Smarty\Cacheresource\Base |
||
349 | * |
||
350 | * @var \Smarty\Cacheresource\Base |
||
351 | */ |
||
352 | private $cacheResource; |
||
353 | |||
354 | /** |
||
355 | * config type |
||
356 | * |
||
357 | * @var string |
||
358 | */ |
||
359 | public $default_config_type = 'file'; |
||
360 | |||
361 | /** |
||
362 | * check If-Modified-Since headers |
||
363 | * |
||
364 | * @var boolean |
||
365 | */ |
||
366 | public $cache_modified_check = false; |
||
367 | |||
368 | /** |
||
369 | * registered plugins |
||
370 | * |
||
371 | * @var array |
||
372 | */ |
||
373 | public $registered_plugins = []; |
||
374 | |||
375 | /** |
||
376 | * registered objects |
||
377 | * |
||
378 | * @var array |
||
379 | */ |
||
380 | public $registered_objects = []; |
||
381 | |||
382 | /** |
||
383 | * registered classes |
||
384 | * |
||
385 | * @var array |
||
386 | */ |
||
387 | public $registered_classes = []; |
||
388 | |||
389 | /** |
||
390 | * registered resources |
||
391 | * |
||
392 | * @var array |
||
393 | */ |
||
394 | public $registered_resources = []; |
||
395 | |||
396 | /** |
||
397 | * registered cache resources |
||
398 | * |
||
399 | * @var array |
||
400 | * @deprecated since 5.0 |
||
401 | */ |
||
402 | private $registered_cache_resources = []; |
||
403 | |||
404 | /** |
||
405 | * default modifier |
||
406 | * |
||
407 | * @var array |
||
408 | */ |
||
409 | public $default_modifiers = []; |
||
410 | |||
411 | /** |
||
412 | * autoescape variable output |
||
413 | * |
||
414 | * @var boolean |
||
415 | */ |
||
416 | public $escape_html = false; |
||
417 | |||
418 | /** |
||
419 | * start time for execution time calculation |
||
420 | * |
||
421 | * @var int |
||
422 | */ |
||
423 | public $start_time = 0; |
||
424 | |||
425 | /** |
||
426 | * internal flag to enable parser debugging |
||
427 | * |
||
428 | * @var bool |
||
429 | */ |
||
430 | public $_parserdebug = false; |
||
431 | |||
432 | /** |
||
433 | * Debug object |
||
434 | * |
||
435 | * @var \Smarty\Debug |
||
436 | */ |
||
437 | public $_debug = null; |
||
438 | |||
439 | /** |
||
440 | * template directory |
||
441 | * |
||
442 | * @var array |
||
443 | */ |
||
444 | protected $template_dir = ['./templates/']; |
||
445 | |||
446 | /** |
||
447 | * flags for normalized template directory entries |
||
448 | * |
||
449 | * @var array |
||
450 | */ |
||
451 | protected $_processedTemplateDir = []; |
||
452 | |||
453 | /** |
||
454 | * config directory |
||
455 | * |
||
456 | * @var array |
||
457 | */ |
||
458 | protected $config_dir = ['./configs/']; |
||
459 | |||
460 | /** |
||
461 | * flags for normalized template directory entries |
||
462 | * |
||
463 | * @var array |
||
464 | */ |
||
465 | protected $_processedConfigDir = []; |
||
466 | |||
467 | /** |
||
468 | * compile directory |
||
469 | * |
||
470 | * @var string |
||
471 | */ |
||
472 | protected $compile_dir = './templates_c/'; |
||
473 | |||
474 | /** |
||
475 | * cache directory |
||
476 | * |
||
477 | * @var string |
||
478 | */ |
||
479 | protected $cache_dir = './cache/'; |
||
480 | |||
481 | /** |
||
482 | * PHP7 Compatibility mode |
||
483 | * |
||
484 | * @var bool |
||
485 | */ |
||
486 | private $isMutingUndefinedOrNullWarnings = false; |
||
487 | |||
488 | /** |
||
489 | * Cache of loaded resource handlers. |
||
490 | * |
||
491 | * @var array |
||
492 | */ |
||
493 | public $_resource_handlers = []; |
||
494 | |||
495 | /** |
||
496 | * Cache of loaded cacheresource handlers. |
||
497 | * |
||
498 | * @var array |
||
499 | */ |
||
500 | public $_cacheresource_handlers = []; |
||
501 | |||
502 | /** |
||
503 | * List of extensions |
||
504 | * |
||
505 | * @var ExtensionInterface[] |
||
506 | */ |
||
507 | private $extensions = []; |
||
508 | /** |
||
509 | * @var BCPluginsAdapter |
||
510 | */ |
||
511 | private $BCPluginsAdapter; |
||
512 | |||
513 | /** |
||
514 | * Initialize new Smarty object |
||
515 | */ |
||
516 | public function __construct() { |
||
517 | |||
518 | $this->start_time = microtime(true); |
||
|
|||
519 | // Check if we're running on Windows |
||
520 | \Smarty\Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; |
||
521 | // let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8 |
||
522 | if (\Smarty\Smarty::$_CHARSET !== 'UTF-8') { |
||
523 | \Smarty\Smarty::$_UTF8_MODIFIER = ''; |
||
524 | } |
||
525 | |||
526 | $this->BCPluginsAdapter = new BCPluginsAdapter($this); |
||
527 | |||
528 | $this->extensions[] = new CoreExtension(); |
||
529 | $this->extensions[] = new DefaultExtension(); |
||
530 | $this->extensions[] = $this->BCPluginsAdapter; |
||
531 | |||
532 | $this->cacheResource = new File(); |
||
533 | } |
||
534 | |||
535 | /** |
||
536 | * Load an additional extension. |
||
537 | * |
||
538 | * @return void |
||
539 | */ |
||
540 | public function addExtension(ExtensionInterface $extension) { |
||
541 | $this->extensions[] = $extension; |
||
542 | } |
||
543 | |||
544 | /** |
||
545 | * Returns all loaded extensions |
||
546 | * |
||
547 | * @return array|ExtensionInterface[] |
||
548 | */ |
||
549 | public function getExtensions(): array { |
||
550 | return $this->extensions; |
||
551 | } |
||
552 | |||
553 | /** |
||
554 | * Replace the entire list extensions, allowing you to determine the exact order of the extensions. |
||
555 | * |
||
556 | * @param ExtensionInterface[] $extensions |
||
557 | * |
||
558 | * @return void |
||
559 | */ |
||
560 | public function setExtensions(array $extensions): void { |
||
561 | $this->extensions = $extensions; |
||
562 | } |
||
563 | |||
564 | /** |
||
565 | * Check if a template resource exists |
||
566 | * |
||
567 | * @param string $resource_name template name |
||
568 | * |
||
569 | * @return bool status |
||
570 | * @throws \Smarty\Exception |
||
571 | */ |
||
572 | public function templateExists($resource_name) { |
||
573 | // create source object |
||
574 | $source = Template\Source::load(null, $this, $resource_name); |
||
575 | return $source->exists; |
||
576 | } |
||
577 | |||
578 | /** |
||
579 | * Loads security class and enables security |
||
580 | * |
||
581 | * @param string|\Smarty\Security $security_class if a string is used, it must be class-name |
||
582 | * |
||
583 | * @return static current Smarty instance for chaining |
||
584 | * @throws \Smarty\Exception |
||
585 | */ |
||
586 | public function enableSecurity($security_class = null) { |
||
587 | \Smarty\Security::enableSecurity($this, $security_class); |
||
588 | return $this; |
||
589 | } |
||
590 | |||
591 | /** |
||
592 | * Disable security |
||
593 | * |
||
594 | * @return static current Smarty instance for chaining |
||
595 | */ |
||
596 | public function disableSecurity() { |
||
597 | $this->security_policy = null; |
||
598 | return $this; |
||
599 | } |
||
600 | |||
601 | /** |
||
602 | * Add template directory(s) |
||
603 | * |
||
604 | * @param string|array $template_dir directory(s) of template sources |
||
605 | * @param string $key of the array element to assign the template dir to |
||
606 | * @param bool $isConfig true for config_dir |
||
607 | * |
||
608 | * @return static current Smarty instance for chaining |
||
609 | */ |
||
610 | public function addTemplateDir($template_dir, $key = null, $isConfig = false) { |
||
611 | if ($isConfig) { |
||
612 | $processed = &$this->_processedConfigDir; |
||
613 | $dir = &$this->config_dir; |
||
614 | $this->_configDirNormalized = false; |
||
615 | } else { |
||
616 | $processed = &$this->_processedTemplateDir; |
||
617 | $dir = &$this->template_dir; |
||
618 | $this->_templateDirNormalized = false; |
||
619 | } |
||
620 | if (is_array($template_dir)) { |
||
621 | foreach ($template_dir as $k => $v) { |
||
622 | if (is_int($k)) { |
||
623 | // indexes are not merged but appended |
||
624 | $dir[] = $v; |
||
625 | } else { |
||
626 | // string indexes are overridden |
||
627 | $dir[$k] = $v; |
||
628 | unset($processed[$key]); |
||
629 | } |
||
630 | } |
||
631 | } else { |
||
632 | if ($key !== null) { |
||
633 | // override directory at specified index |
||
634 | $dir[$key] = $template_dir; |
||
635 | unset($processed[$key]); |
||
636 | } else { |
||
637 | // append new directory |
||
638 | $dir[] = $template_dir; |
||
639 | } |
||
640 | } |
||
641 | return $this; |
||
642 | } |
||
643 | |||
644 | /** |
||
645 | * Get template directories |
||
646 | * |
||
647 | * @param mixed $index index of directory to get, null to get all |
||
648 | * @param bool $isConfig true for config_dir |
||
649 | * |
||
650 | * @return array|string list of template directories, or directory of $index |
||
651 | */ |
||
652 | public function getTemplateDir($index = null, $isConfig = false) { |
||
653 | if ($isConfig) { |
||
654 | $dir = &$this->config_dir; |
||
655 | } else { |
||
656 | $dir = &$this->template_dir; |
||
657 | } |
||
658 | if ($isConfig ? !$this->_configDirNormalized : !$this->_templateDirNormalized) { |
||
659 | $this->_normalizeTemplateConfig($isConfig); |
||
660 | } |
||
661 | if ($index !== null) { |
||
662 | return isset($dir[$index]) ? $dir[$index] : null; |
||
663 | } |
||
664 | return $dir; |
||
665 | } |
||
666 | |||
667 | /** |
||
668 | * Set template directory |
||
669 | * |
||
670 | * @param string|array $template_dir directory(s) of template sources |
||
671 | * @param bool $isConfig true for config_dir |
||
672 | * |
||
673 | * @return static current Smarty instance for chaining |
||
674 | */ |
||
675 | public function setTemplateDir($template_dir, $isConfig = false) { |
||
676 | if ($isConfig) { |
||
677 | $this->config_dir = []; |
||
678 | $this->_processedConfigDir = []; |
||
679 | } else { |
||
680 | $this->template_dir = []; |
||
681 | $this->_processedTemplateDir = []; |
||
682 | } |
||
683 | $this->addTemplateDir($template_dir, null, $isConfig); |
||
684 | return $this; |
||
685 | } |
||
686 | |||
687 | /** |
||
688 | * Adds a template directory before any existing directoires |
||
689 | * |
||
690 | * @param string $new_template_dir directory of template sources |
||
691 | * @param bool $is_config true for config_dir |
||
692 | * |
||
693 | * @return static current Smarty instance for chaining |
||
694 | */ |
||
695 | public function prependTemplateDir($new_template_dir, $is_config = false) { |
||
696 | $current_template_dirs = $is_config ? $this->config_dir : $this->template_dir; |
||
697 | array_unshift($current_template_dirs, $new_template_dir); |
||
698 | $this->setTemplateDir($current_template_dirs, $is_config); |
||
699 | return $this; |
||
700 | } |
||
701 | |||
702 | /** |
||
703 | * Add config directory(s) |
||
704 | * |
||
705 | * @param string|array $config_dir directory(s) of config sources |
||
706 | * @param mixed $key key of the array element to assign the config dir to |
||
707 | * |
||
708 | * @return static current Smarty instance for chaining |
||
709 | */ |
||
710 | public function addConfigDir($config_dir, $key = null) { |
||
711 | return $this->addTemplateDir($config_dir, $key, true); |
||
712 | } |
||
713 | |||
714 | /** |
||
715 | * Get config directory |
||
716 | * |
||
717 | * @param mixed $index index of directory to get, null to get all |
||
718 | * |
||
719 | * @return array configuration directory |
||
720 | */ |
||
721 | public function getConfigDir($index = null) { |
||
722 | return $this->getTemplateDir($index, true); |
||
723 | } |
||
724 | |||
725 | /** |
||
726 | * Set config directory |
||
727 | * |
||
728 | * @param $config_dir |
||
729 | * |
||
730 | * @return static current Smarty instance for chaining |
||
731 | */ |
||
732 | public function setConfigDir($config_dir) { |
||
733 | return $this->setTemplateDir($config_dir, true); |
||
734 | } |
||
735 | |||
736 | /** |
||
737 | * Registers plugin to be used in templates |
||
738 | * |
||
739 | * @param string $type plugin type |
||
740 | * @param string $name name of template tag |
||
741 | * @param callable $callback PHP callback to register |
||
742 | * @param bool $cacheable if true (default) this function is cache able |
||
743 | * |
||
744 | * @return $this |
||
745 | * @throws \Smarty\Exception |
||
746 | * |
||
747 | * @api Smarty::registerPlugin() |
||
748 | */ |
||
749 | public function registerPlugin($type, $name, $callback, $cacheable = true) { |
||
750 | if (isset($this->registered_plugins[$type][$name])) { |
||
751 | throw new Exception("Plugin tag '{$name}' already registered"); |
||
752 | } elseif (!is_callable($callback) && !class_exists($callback)) { |
||
753 | throw new Exception("Plugin '{$name}' not callable"); |
||
754 | } else { |
||
755 | $this->registered_plugins[$type][$name] = [$callback, (bool)$cacheable]; |
||
756 | } |
||
757 | return $this; |
||
758 | } |
||
759 | |||
760 | /** |
||
761 | * Returns plugin previously registered using ::registerPlugin as a numerical array as follows or null if not found: |
||
762 | * [ |
||
763 | * 0 => the callback |
||
764 | * 1 => (bool) $cacheable |
||
765 | * 2 => (array) $cache_attr |
||
766 | * ] |
||
767 | * |
||
768 | * @param string $type plugin type |
||
769 | * @param string $name name of template tag |
||
770 | * |
||
771 | * @return array|null |
||
772 | * |
||
773 | * @api Smarty::unregisterPlugin() |
||
774 | */ |
||
775 | public function getRegisteredPlugin($type, $name): ?array { |
||
776 | if (isset($this->registered_plugins[$type][$name])) { |
||
777 | return $this->registered_plugins[$type][$name]; |
||
778 | } |
||
779 | return null; |
||
780 | } |
||
781 | |||
782 | /** |
||
783 | * Unregisters plugin previously registered using ::registerPlugin |
||
784 | * |
||
785 | * @param string $type plugin type |
||
786 | * @param string $name name of template tag |
||
787 | * |
||
788 | * @return $this |
||
789 | * |
||
790 | * @api Smarty::unregisterPlugin() |
||
791 | */ |
||
792 | public function unregisterPlugin($type, $name) { |
||
793 | if (isset($this->registered_plugins[$type][$name])) { |
||
794 | unset($this->registered_plugins[$type][$name]); |
||
795 | } |
||
796 | return $this; |
||
797 | } |
||
798 | |||
799 | /** |
||
800 | * Adds directory of plugin files |
||
801 | * |
||
802 | * @param null|array|string $plugins_dir |
||
803 | * |
||
804 | * @return static current Smarty instance for chaining |
||
805 | * @deprecated since 5.0 |
||
806 | */ |
||
807 | public function addPluginsDir($plugins_dir) { |
||
808 | trigger_error('Using Smarty::addPluginsDir() to load plugins is deprecated and will be ' . |
||
809 | 'removed in a future release. Use Smarty::addExtension() to add an extension or Smarty::registerPlugin to ' . |
||
810 | 'quickly register a plugin using a callback function.', E_USER_DEPRECATED); |
||
811 | |||
812 | foreach ((array)$plugins_dir as $v) { |
||
813 | $path = $this->_realpath(rtrim($v ?? '', '/\\') . DIRECTORY_SEPARATOR, true); |
||
814 | $this->BCPluginsAdapter->loadPluginsFromDir($path); |
||
815 | } |
||
816 | |||
817 | return $this; |
||
818 | } |
||
819 | |||
820 | /** |
||
821 | * Get plugin directories |
||
822 | * |
||
823 | * @return array list of plugin directories |
||
824 | * @deprecated since 5.0 |
||
825 | */ |
||
826 | public function getPluginsDir() { |
||
827 | trigger_error('Using Smarty::getPluginsDir() is deprecated and will be ' . |
||
828 | 'removed in a future release. It will always return an empty array.', E_USER_DEPRECATED); |
||
829 | return []; |
||
830 | } |
||
831 | |||
832 | /** |
||
833 | * Set plugins directory |
||
834 | * |
||
835 | * @param string|array $plugins_dir directory(s) of plugins |
||
836 | * |
||
837 | * @return static current Smarty instance for chaining |
||
838 | * @deprecated since 5.0 |
||
839 | */ |
||
840 | public function setPluginsDir($plugins_dir) { |
||
841 | trigger_error('Using Smarty::getPluginsDir() is deprecated and will be ' . |
||
842 | 'removed in a future release. For now, it will remove the DefaultExtension from the extensions list and ' . |
||
843 | 'proceed to call Smartyy::addPluginsDir..', E_USER_DEPRECATED); |
||
844 | |||
845 | $this->extensions = array_filter( |
||
846 | $this->extensions, |
||
847 | function ($extension) { |
||
848 | return !($extension instanceof DefaultExtension); |
||
849 | } |
||
850 | ); |
||
851 | |||
852 | return $this->addPluginsDir($plugins_dir); |
||
853 | } |
||
854 | |||
855 | /** |
||
856 | * Registers a default plugin handler |
||
857 | * |
||
858 | * @param callable $callback class/method name |
||
859 | * |
||
860 | * @return $this |
||
861 | * @throws Exception if $callback is not callable |
||
862 | * |
||
863 | * @api Smarty::registerDefaultPluginHandler() |
||
864 | * |
||
865 | * @deprecated since 5.0 |
||
866 | */ |
||
867 | public function registerDefaultPluginHandler($callback) { |
||
868 | |||
869 | trigger_error('Using Smarty::registerDefaultPluginHandler() is deprecated and will be ' . |
||
870 | 'removed in a future release. Please rewrite your plugin handler as an extension.', |
||
871 | E_USER_DEPRECATED); |
||
872 | |||
873 | if (is_callable($callback)) { |
||
874 | $this->default_plugin_handler_func = $callback; |
||
875 | } else { |
||
876 | throw new Exception("Default plugin handler '$callback' not callable"); |
||
877 | } |
||
878 | return $this; |
||
879 | } |
||
880 | |||
881 | /** |
||
882 | * Get compiled directory |
||
883 | * |
||
884 | * @return string path to compiled templates |
||
885 | */ |
||
886 | public function getCompileDir() { |
||
887 | if (!$this->_compileDirNormalized) { |
||
888 | $this->_normalizeDir('compile_dir', $this->compile_dir); |
||
889 | $this->_compileDirNormalized = true; |
||
890 | } |
||
891 | return $this->compile_dir; |
||
892 | } |
||
893 | |||
894 | /** |
||
895 | * |
||
896 | * @param string $compile_dir directory to store compiled templates in |
||
897 | * |
||
898 | * @return static current Smarty instance for chaining |
||
899 | */ |
||
900 | public function setCompileDir($compile_dir) { |
||
901 | $this->_normalizeDir('compile_dir', $compile_dir); |
||
902 | $this->_compileDirNormalized = true; |
||
903 | return $this; |
||
904 | } |
||
905 | |||
906 | /** |
||
907 | * Get cache directory |
||
908 | * |
||
909 | * @return string path of cache directory |
||
910 | */ |
||
911 | public function getCacheDir() { |
||
912 | if (!$this->_cacheDirNormalized) { |
||
913 | $this->_normalizeDir('cache_dir', $this->cache_dir); |
||
914 | $this->_cacheDirNormalized = true; |
||
915 | } |
||
916 | return $this->cache_dir; |
||
917 | } |
||
918 | |||
919 | /** |
||
920 | * Set cache directory |
||
921 | * |
||
922 | * @param string $cache_dir directory to store cached templates in |
||
923 | * |
||
924 | * @return static current Smarty instance for chaining |
||
925 | */ |
||
926 | public function setCacheDir($cache_dir) { |
||
927 | $this->_normalizeDir('cache_dir', $cache_dir); |
||
928 | $this->_cacheDirNormalized = true; |
||
929 | return $this; |
||
930 | } |
||
931 | |||
932 | private $templates = []; |
||
933 | |||
934 | /** |
||
935 | * Creates a template object |
||
936 | * |
||
937 | * @param string $template_name |
||
938 | * @param mixed $cache_id cache id to be used with this template |
||
939 | * @param mixed $compile_id compile id to be used with this template |
||
940 | * @param null $parent next higher level of Smarty variables |
||
941 | * |
||
942 | * @return Template template object |
||
943 | * @throws Exception |
||
944 | */ |
||
945 | public function createTemplate($template_name, $cache_id = null, $compile_id = null, $parent = null): Template { |
||
946 | |||
947 | $data = []; |
||
948 | |||
949 | // Shuffle params for backward compatibility: if 2nd param is an object, it's the parent |
||
950 | if (is_object($cache_id)) { |
||
951 | $parent = $cache_id; |
||
952 | $cache_id = null; |
||
953 | } |
||
954 | |||
955 | // Shuffle params for backward compatibility: if 2nd param is an array, it's data |
||
956 | if (is_array($cache_id)) { |
||
957 | $data = $cache_id; |
||
958 | $cache_id = null; |
||
959 | } |
||
960 | |||
961 | return $this->doCreateTemplate($template_name, $cache_id, $compile_id, $parent, null, null, false, $data); |
||
962 | } |
||
963 | |||
964 | /** |
||
965 | * Get unique template id |
||
966 | * |
||
967 | * @param string $resource_name |
||
968 | * @param null|mixed $cache_id |
||
969 | * @param null|mixed $compile_id |
||
970 | * @param null $caching |
||
971 | * |
||
972 | * @return string |
||
973 | */ |
||
974 | private function generateUniqueTemplateId( |
||
999 | } |
||
1000 | |||
1001 | /** |
||
1002 | * Normalize path |
||
1003 | * - remove /./ and /../ |
||
1004 | * - make it absolute if required |
||
1005 | * |
||
1006 | * @param string $path file path |
||
1007 | * @param bool $realpath if true - convert to absolute |
||
1008 | * false - convert to relative |
||
1009 | * null - keep as it is but |
||
1010 | * remove /./ /../ |
||
1011 | * |
||
1012 | * @return string |
||
1013 | */ |
||
1014 | public function _realpath($path, $realpath = null) { |
||
1015 | $nds = ['/' => '\\', '\\' => '/']; |
||
1016 | preg_match( |
||
1017 | '%^(?<root>(?:[[:alpha:]]:[\\\\/]|/|[\\\\]{2}[[:alpha:]]+|[[:print:]]{2,}:[/]{2}|[\\\\])?)(?<path>(.*))$%u', |
||
1018 | $path, |
||
1019 | $parts |
||
1020 | ); |
||
1021 | $path = $parts['path']; |
||
1022 | if ($parts['root'] === '\\') { |
||
1023 | $parts['root'] = substr(getcwd(), 0, 2) . $parts['root']; |
||
1024 | } else { |
||
1025 | if ($realpath !== null && !$parts['root']) { |
||
1026 | $path = getcwd() . DIRECTORY_SEPARATOR . $path; |
||
1027 | } |
||
1028 | } |
||
1029 | // normalize DIRECTORY_SEPARATOR |
||
1030 | $path = str_replace($nds[DIRECTORY_SEPARATOR], DIRECTORY_SEPARATOR, $path); |
||
1031 | $parts['root'] = str_replace($nds[DIRECTORY_SEPARATOR], DIRECTORY_SEPARATOR, $parts['root']); |
||
1032 | do { |
||
1033 | $path = preg_replace( |
||
1034 | ['#[\\\\/]{2}#', '#[\\\\/][.][\\\\/]#', '#[\\\\/]([^\\\\/.]+)[\\\\/][.][.][\\\\/]#'], |
||
1035 | DIRECTORY_SEPARATOR, |
||
1036 | $path, |
||
1037 | -1, |
||
1038 | $count |
||
1039 | ); |
||
1040 | } while ($count > 0); |
||
1041 | return $realpath !== false ? $parts['root'] . $path : str_ireplace(getcwd(), '.', $parts['root'] . $path); |
||
1042 | } |
||
1043 | |||
1044 | /** |
||
1045 | * @param boolean $use_sub_dirs |
||
1046 | */ |
||
1047 | public function setUseSubDirs($use_sub_dirs) { |
||
1048 | $this->use_sub_dirs = $use_sub_dirs; |
||
1049 | } |
||
1050 | |||
1051 | /** |
||
1052 | * @param int $error_reporting |
||
1053 | */ |
||
1054 | public function setErrorReporting($error_reporting) { |
||
1055 | $this->error_reporting = $error_reporting; |
||
1056 | } |
||
1057 | |||
1058 | /** |
||
1059 | * @param boolean $escape_html |
||
1060 | */ |
||
1061 | public function setEscapeHtml($escape_html) { |
||
1062 | $this->escape_html = $escape_html; |
||
1063 | } |
||
1064 | |||
1065 | /** |
||
1066 | * Return auto_literal flag |
||
1067 | * |
||
1068 | * @return boolean |
||
1069 | */ |
||
1070 | public function getAutoLiteral() { |
||
1071 | return $this->auto_literal; |
||
1072 | } |
||
1073 | |||
1074 | /** |
||
1075 | * Set auto_literal flag |
||
1076 | * |
||
1077 | * @param boolean $auto_literal |
||
1078 | */ |
||
1079 | public function setAutoLiteral($auto_literal = true) { |
||
1080 | $this->auto_literal = $auto_literal; |
||
1081 | } |
||
1082 | |||
1083 | /** |
||
1084 | * @param boolean $force_compile |
||
1085 | */ |
||
1086 | public function setForceCompile($force_compile) { |
||
1087 | $this->force_compile = $force_compile; |
||
1088 | } |
||
1089 | |||
1090 | /** |
||
1091 | * @param boolean $merge_compiled_includes |
||
1092 | */ |
||
1093 | public function setMergeCompiledIncludes($merge_compiled_includes) { |
||
1094 | $this->merge_compiled_includes = $merge_compiled_includes; |
||
1095 | } |
||
1096 | |||
1097 | /** |
||
1098 | * Get left delimiter |
||
1099 | * |
||
1100 | * @return string |
||
1101 | */ |
||
1102 | public function getLeftDelimiter() { |
||
1103 | return $this->left_delimiter; |
||
1104 | } |
||
1105 | |||
1106 | /** |
||
1107 | * Set left delimiter |
||
1108 | * |
||
1109 | * @param string $left_delimiter |
||
1110 | */ |
||
1111 | public function setLeftDelimiter($left_delimiter) { |
||
1112 | $this->left_delimiter = $left_delimiter; |
||
1113 | } |
||
1114 | |||
1115 | /** |
||
1116 | * Get right delimiter |
||
1117 | * |
||
1118 | * @return string $right_delimiter |
||
1119 | */ |
||
1120 | public function getRightDelimiter() { |
||
1121 | return $this->right_delimiter; |
||
1122 | } |
||
1123 | |||
1124 | /** |
||
1125 | * Set right delimiter |
||
1126 | * |
||
1127 | * @param string |
||
1128 | */ |
||
1129 | public function setRightDelimiter($right_delimiter) { |
||
1130 | $this->right_delimiter = $right_delimiter; |
||
1131 | } |
||
1132 | |||
1133 | /** |
||
1134 | * @param boolean $debugging |
||
1135 | */ |
||
1136 | public function setDebugging($debugging) { |
||
1137 | $this->debugging = $debugging; |
||
1138 | } |
||
1139 | |||
1140 | /** |
||
1141 | * @param boolean $config_overwrite |
||
1142 | */ |
||
1143 | public function setConfigOverwrite($config_overwrite) { |
||
1144 | $this->config_overwrite = $config_overwrite; |
||
1145 | } |
||
1146 | |||
1147 | /** |
||
1148 | * @param boolean $config_booleanize |
||
1149 | */ |
||
1150 | public function setConfigBooleanize($config_booleanize) { |
||
1151 | $this->config_booleanize = $config_booleanize; |
||
1152 | } |
||
1153 | |||
1154 | /** |
||
1155 | * @param boolean $config_read_hidden |
||
1156 | */ |
||
1157 | public function setConfigReadHidden($config_read_hidden) { |
||
1158 | $this->config_read_hidden = $config_read_hidden; |
||
1159 | } |
||
1160 | |||
1161 | /** |
||
1162 | * @param boolean $compile_locking |
||
1163 | */ |
||
1164 | public function setCompileLocking($compile_locking) { |
||
1165 | $this->compile_locking = $compile_locking; |
||
1166 | } |
||
1167 | |||
1168 | /** |
||
1169 | * @param string $default_resource_type |
||
1170 | */ |
||
1171 | public function setDefaultResourceType($default_resource_type) { |
||
1172 | $this->default_resource_type = $default_resource_type; |
||
1173 | } |
||
1174 | |||
1175 | /** |
||
1176 | * Test install |
||
1177 | * |
||
1178 | * @param null $errors |
||
1179 | */ |
||
1180 | public function testInstall(&$errors = null) { |
||
1181 | \Smarty\TestInstall::testInstall($this, $errors); |
||
1182 | } |
||
1183 | |||
1184 | /** |
||
1185 | * Get Smarty object |
||
1186 | * |
||
1187 | * @return static |
||
1188 | */ |
||
1189 | public function getSmarty() { |
||
1190 | return $this; |
||
1191 | } |
||
1192 | |||
1193 | /** |
||
1194 | * Normalize and set directory string |
||
1195 | * |
||
1196 | * @param string $dirName cache_dir or compile_dir |
||
1197 | * @param string $dir filepath of folder |
||
1198 | */ |
||
1199 | private function _normalizeDir($dirName, $dir) { |
||
1200 | $this->{$dirName} = $this->_realpath(rtrim($dir ?? '', "/\\") . DIRECTORY_SEPARATOR, true); |
||
1201 | } |
||
1202 | |||
1203 | /** |
||
1204 | * Normalize template_dir or config_dir |
||
1205 | * |
||
1206 | * @param bool $isConfig true for config_dir |
||
1207 | */ |
||
1208 | private function _normalizeTemplateConfig($isConfig) { |
||
1209 | if ($isConfig) { |
||
1210 | $processed = &$this->_processedConfigDir; |
||
1211 | $dir = &$this->config_dir; |
||
1212 | } else { |
||
1213 | $processed = &$this->_processedTemplateDir; |
||
1214 | $dir = &$this->template_dir; |
||
1215 | } |
||
1216 | if (!is_array($dir)) { |
||
1217 | $dir = (array)$dir; |
||
1218 | } |
||
1219 | foreach ($dir as $k => $v) { |
||
1220 | if (!isset($processed[$k])) { |
||
1221 | $dir[$k] = $this->_realpath(rtrim($v ?? '', "/\\") . DIRECTORY_SEPARATOR, true); |
||
1222 | $processed[$k] = true; |
||
1223 | } |
||
1224 | } |
||
1225 | |||
1226 | if ($isConfig) { |
||
1227 | $this->_configDirNormalized = true; |
||
1228 | $this->_joined_config_dir = join('#', $this->config_dir); |
||
1229 | } else { |
||
1230 | $this->_templateDirNormalized = true; |
||
1231 | $this->_joined_template_dir = join('#', $this->template_dir); |
||
1232 | } |
||
1233 | |||
1234 | } |
||
1235 | |||
1236 | /** |
||
1237 | * Mutes errors for "undefined index", "undefined array key" and "trying to read property of null". |
||
1238 | * |
||
1239 | * @void |
||
1240 | */ |
||
1241 | public function muteUndefinedOrNullWarnings(): void { |
||
1242 | $this->isMutingUndefinedOrNullWarnings = true; |
||
1243 | } |
||
1244 | |||
1245 | /** |
||
1246 | * Indicates if Smarty will mute errors for "undefined index", "undefined array key" and "trying to read property of null". |
||
1247 | * |
||
1248 | * @return bool |
||
1249 | */ |
||
1250 | public function isMutingUndefinedOrNullWarnings(): bool { |
||
1251 | return $this->isMutingUndefinedOrNullWarnings; |
||
1252 | } |
||
1253 | |||
1254 | /** |
||
1255 | * Empty cache for a specific template |
||
1256 | * |
||
1257 | * @param string $template_name template name |
||
1258 | * @param string $cache_id cache id |
||
1259 | * @param string $compile_id compile id |
||
1260 | * @param integer $exp_time expiration time |
||
1261 | * @param string $type resource type |
||
1262 | * |
||
1263 | * @return int number of cache files deleted |
||
1264 | * @throws \Smarty\Exception |
||
1265 | * |
||
1266 | * @api Smarty::clearCache() |
||
1267 | */ |
||
1268 | public function clearCache( |
||
1269 | $template_name, |
||
1270 | $cache_id = null, |
||
1271 | $compile_id = null, |
||
1272 | $exp_time = null |
||
1273 | ) { |
||
1274 | return $this->getCacheResource()->clear($this, $template_name, $cache_id, $compile_id, $exp_time); |
||
1275 | } |
||
1276 | |||
1277 | /** |
||
1278 | * Empty cache folder |
||
1279 | * |
||
1280 | * @param integer $exp_time expiration time |
||
1281 | * @param string $type resource type |
||
1282 | * |
||
1283 | * @return int number of cache files deleted |
||
1284 | * |
||
1285 | * @api Smarty::clearAllCache() |
||
1286 | */ |
||
1287 | public function clearAllCache($exp_time = null) { |
||
1288 | return $this->getCacheResource()->clearAll($this, $exp_time); |
||
1289 | } |
||
1290 | |||
1291 | /** |
||
1292 | * Delete compiled template file |
||
1293 | * |
||
1294 | * @param string $resource_name template name |
||
1295 | * @param string $compile_id compile id |
||
1296 | * @param integer $exp_time expiration time |
||
1297 | * |
||
1298 | * @return int number of template files deleted |
||
1299 | * @throws \Smarty\Exception |
||
1300 | * |
||
1301 | * @api Smarty::clearCompiledTemplate() |
||
1302 | */ |
||
1303 | public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null) { |
||
1304 | $_compile_dir = $this->getCompileDir(); |
||
1305 | if ($_compile_dir === '/') { //We should never want to delete this! |
||
1306 | return 0; |
||
1307 | } |
||
1308 | $_compile_id = isset($compile_id) ? preg_replace('![^\w]+!', '_', $compile_id) : null; |
||
1309 | $_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^'; |
||
1310 | if (isset($resource_name)) { |
||
1311 | $_save_stat = $this->caching; |
||
1312 | $this->caching = \Smarty\Smarty::CACHING_OFF; |
||
1313 | /* @var Template $tpl */ |
||
1314 | $tpl = $this->doCreateTemplate($resource_name); |
||
1315 | $this->caching = $_save_stat; |
||
1316 | if (!$tpl->getSource()->handler->recompiled && $tpl->getSource()->exists) { |
||
1317 | $_resource_part_1 = basename(str_replace('^', DIRECTORY_SEPARATOR, $tpl->getCompiled()->filepath)); |
||
1318 | $_resource_part_1_length = strlen($_resource_part_1); |
||
1319 | } else { |
||
1320 | return 0; |
||
1321 | } |
||
1322 | $_resource_part_2 = str_replace('.php', '.cache.php', $_resource_part_1); |
||
1323 | $_resource_part_2_length = strlen($_resource_part_2); |
||
1324 | } |
||
1325 | $_dir = $_compile_dir; |
||
1326 | if ($this->use_sub_dirs && isset($_compile_id)) { |
||
1327 | $_dir .= $_compile_id . $_dir_sep; |
||
1328 | } |
||
1329 | if (isset($_compile_id)) { |
||
1330 | $_compile_id_part = $_compile_dir . $_compile_id . $_dir_sep; |
||
1331 | $_compile_id_part_length = strlen($_compile_id_part); |
||
1332 | } |
||
1333 | $_count = 0; |
||
1334 | try { |
||
1335 | $_compileDirs = new RecursiveDirectoryIterator($_dir); |
||
1336 | } catch (\UnexpectedValueException $e) { |
||
1337 | // path not found / not a dir |
||
1338 | return 0; |
||
1339 | } |
||
1340 | $_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST); |
||
1341 | foreach ($_compile as $_file) { |
||
1342 | if (substr(basename($_file->getPathname()), 0, 1) === '.') { |
||
1343 | continue; |
||
1344 | } |
||
1345 | $_filepath = (string)$_file; |
||
1346 | if ($_file->isDir()) { |
||
1347 | if (!$_compile->isDot()) { |
||
1348 | // delete folder if empty |
||
1349 | @rmdir($_file->getPathname()); |
||
1350 | } |
||
1351 | } else { |
||
1352 | // delete only php files |
||
1353 | if (substr($_filepath, -4) !== '.php') { |
||
1354 | continue; |
||
1355 | } |
||
1356 | $unlink = false; |
||
1357 | if ((!isset($_compile_id) || |
||
1358 | (isset($_filepath[$_compile_id_part_length]) && |
||
1359 | $a = !strncmp($_filepath, $_compile_id_part, $_compile_id_part_length))) |
||
1360 | && (!isset($resource_name) || (isset($_filepath[$_resource_part_1_length]) |
||
1361 | && substr_compare( |
||
1362 | $_filepath, |
||
1363 | $_resource_part_1, |
||
1364 | -$_resource_part_1_length, |
||
1365 | $_resource_part_1_length |
||
1366 | ) === 0) || (isset($_filepath[$_resource_part_2_length]) |
||
1367 | && substr_compare( |
||
1368 | $_filepath, |
||
1369 | $_resource_part_2, |
||
1370 | -$_resource_part_2_length, |
||
1371 | $_resource_part_2_length |
||
1372 | ) === 0)) |
||
1373 | ) { |
||
1374 | if (isset($exp_time)) { |
||
1375 | if (is_file($_filepath) && time() - filemtime($_filepath) >= $exp_time) { |
||
1376 | $unlink = true; |
||
1377 | } |
||
1378 | } else { |
||
1379 | $unlink = true; |
||
1380 | } |
||
1381 | } |
||
1382 | if ($unlink && is_file($_filepath) && @unlink($_filepath)) { |
||
1383 | $_count++; |
||
1384 | if (function_exists('opcache_invalidate') |
||
1385 | && (!function_exists('ini_get') || strlen(ini_get('opcache.restrict_api')) < 1) |
||
1386 | ) { |
||
1387 | opcache_invalidate($_filepath, true); |
||
1388 | } elseif (function_exists('apc_delete_file')) { |
||
1389 | apc_delete_file($_filepath); |
||
1390 | } |
||
1391 | } |
||
1392 | } |
||
1393 | } |
||
1394 | return $_count; |
||
1395 | } |
||
1396 | |||
1397 | /** |
||
1398 | * Compile all template files |
||
1399 | * |
||
1400 | * @param string $extension file extension |
||
1401 | * @param bool $force_compile force all to recompile |
||
1402 | * @param int $time_limit |
||
1403 | * @param int $max_errors |
||
1404 | * |
||
1405 | * @return integer number of template files recompiled |
||
1406 | * @api Smarty::compileAllTemplates() |
||
1407 | * |
||
1408 | */ |
||
1409 | public function compileAllTemplates( |
||
1410 | $extension = '.tpl', |
||
1411 | $force_compile = false, |
||
1412 | $time_limit = 0, |
||
1413 | $max_errors = null |
||
1414 | ) { |
||
1415 | return $this->compileAll($extension, $force_compile, $time_limit, $max_errors); |
||
1416 | } |
||
1417 | |||
1418 | /** |
||
1419 | * Compile all config files |
||
1420 | * |
||
1421 | * @param string $extension file extension |
||
1422 | * @param bool $force_compile force all to recompile |
||
1423 | * @param int $time_limit |
||
1424 | * @param int $max_errors |
||
1425 | * |
||
1426 | * @return int number of template files recompiled |
||
1427 | * @api Smarty::compileAllConfig() |
||
1428 | * |
||
1429 | */ |
||
1430 | public function compileAllConfig( |
||
1431 | $extension = '.conf', |
||
1432 | $force_compile = false, |
||
1433 | $time_limit = 0, |
||
1434 | $max_errors = null |
||
1435 | ) { |
||
1436 | return $this->compileAll($extension, $force_compile, $time_limit, $max_errors, true); |
||
1437 | } |
||
1438 | |||
1439 | /** |
||
1440 | * Compile all template or config files |
||
1441 | * |
||
1442 | * @param string $extension template file name extension |
||
1443 | * @param bool $force_compile force all to recompile |
||
1444 | * @param int $time_limit set maximum execution time |
||
1445 | * @param int $max_errors set maximum allowed errors |
||
1446 | * @param bool $isConfig flag true if called for config files |
||
1447 | * |
||
1448 | * @return int number of template files compiled |
||
1449 | */ |
||
1450 | protected function compileAll( |
||
1451 | $extension, |
||
1452 | $force_compile, |
||
1453 | $time_limit, |
||
1454 | $max_errors, |
||
1455 | $isConfig = false |
||
1456 | ) { |
||
1457 | // switch off time limit |
||
1458 | if (function_exists('set_time_limit')) { |
||
1459 | @set_time_limit($time_limit); |
||
1460 | } |
||
1461 | $_count = 0; |
||
1462 | $_error_count = 0; |
||
1463 | $sourceDir = $isConfig ? $this->getConfigDir() : $this->getTemplateDir(); |
||
1464 | // loop over array of source directories |
||
1465 | foreach ($sourceDir as $_dir) { |
||
1466 | $_dir_1 = new RecursiveDirectoryIterator( |
||
1467 | $_dir, |
||
1468 | defined('FilesystemIterator::FOLLOW_SYMLINKS') ? |
||
1469 | FilesystemIterator::FOLLOW_SYMLINKS : 0 |
||
1470 | ); |
||
1471 | $_dir_2 = new RecursiveIteratorIterator($_dir_1); |
||
1472 | foreach ($_dir_2 as $_fileinfo) { |
||
1473 | $_file = $_fileinfo->getFilename(); |
||
1474 | if (substr(basename($_fileinfo->getPathname()), 0, 1) === '.' || strpos($_file, '.svn') !== false) { |
||
1475 | continue; |
||
1476 | } |
||
1477 | if (substr_compare($_file, $extension, -strlen($extension)) !== 0) { |
||
1478 | continue; |
||
1479 | } |
||
1480 | if ($_fileinfo->getPath() !== substr($_dir, 0, -1)) { |
||
1481 | $_file = substr($_fileinfo->getPath(), strlen($_dir)) . DIRECTORY_SEPARATOR . $_file; |
||
1482 | } |
||
1483 | echo "\n", $_dir, '---', $_file; |
||
1484 | flush(); |
||
1485 | $_start_time = microtime(true); |
||
1486 | $_smarty = clone $this; |
||
1487 | // |
||
1488 | $_smarty->force_compile = $force_compile; |
||
1489 | try { |
||
1490 | $_tpl = $this->doCreateTemplate($_file); |
||
1491 | $_tpl->caching = self::CACHING_OFF; |
||
1492 | $_tpl->setSource( |
||
1493 | $isConfig ? \Smarty\Template\Config::load($_tpl) : \Smarty\Template\Source::load($_tpl) |
||
1494 | ); |
||
1495 | if ($_tpl->mustCompile()) { |
||
1496 | $_tpl->compileTemplateSource(); |
||
1497 | $_count++; |
||
1498 | echo ' compiled in ', microtime(true) - $_start_time, ' seconds'; |
||
1499 | flush(); |
||
1500 | } else { |
||
1501 | echo ' is up to date'; |
||
1502 | flush(); |
||
1503 | } |
||
1504 | } catch (\Exception $e) { |
||
1505 | echo "\n ------>Error: ", $e->getMessage(), "\n"; |
||
1506 | $_error_count++; |
||
1507 | } |
||
1508 | // free memory |
||
1509 | unset($_tpl); |
||
1510 | if ($max_errors !== null && $_error_count === $max_errors) { |
||
1511 | echo "\ntoo many errors\n"; |
||
1512 | exit(1); |
||
1513 | } |
||
1514 | } |
||
1515 | } |
||
1516 | echo "\n"; |
||
1517 | return $_count; |
||
1518 | } |
||
1519 | |||
1520 | /** |
||
1521 | * check client side cache |
||
1522 | * |
||
1523 | * @param \Smarty\Template\Cached $cached |
||
1524 | * @param Template $_template |
||
1525 | * @param string $content |
||
1526 | * |
||
1527 | * @throws \Exception |
||
1528 | * @throws \Smarty\Exception |
||
1529 | */ |
||
1530 | public function cacheModifiedCheck(Template\Cached $cached, Template $_template, $content) { |
||
1531 | $_isCached = $_template->isCached() && !$_template->getCompiled()->getNocacheCode(); |
||
1532 | $_last_modified_date = |
||
1533 | @substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); |
||
1534 | if ($_isCached && $cached->timestamp <= strtotime($_last_modified_date)) { |
||
1535 | switch (PHP_SAPI) { |
||
1536 | case 'cgi': // php-cgi < 5.3 |
||
1537 | case 'cgi-fcgi': // php-cgi >= 5.3 |
||
1538 | case 'fpm-fcgi': // php-fpm >= 5.3.3 |
||
1539 | header('Status: 304 Not Modified'); |
||
1540 | break; |
||
1541 | case 'cli': |
||
1542 | if (/* ^phpunit */ |
||
1543 | !empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']) /* phpunit$ */ |
||
1544 | ) { |
||
1545 | $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = '304 Not Modified'; |
||
1546 | } |
||
1547 | break; |
||
1548 | default: |
||
1549 | if (/* ^phpunit */ |
||
1550 | !empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']) /* phpunit$ */ |
||
1551 | ) { |
||
1552 | $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = '304 Not Modified'; |
||
1553 | } else { |
||
1554 | header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified'); |
||
1555 | } |
||
1556 | break; |
||
1557 | } |
||
1558 | } else { |
||
1559 | switch (PHP_SAPI) { |
||
1560 | case 'cli': |
||
1561 | if (/* ^phpunit */ |
||
1562 | !empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']) /* phpunit$ */ |
||
1563 | ) { |
||
1564 | $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = |
||
1565 | 'Last-Modified: ' . gmdate('D, d M Y H:i:s', $cached->timestamp) . ' GMT'; |
||
1566 | } |
||
1567 | break; |
||
1568 | default: |
||
1569 | header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $cached->timestamp) . ' GMT'); |
||
1570 | break; |
||
1571 | } |
||
1572 | echo $content; |
||
1573 | } |
||
1574 | } |
||
1575 | |||
1576 | public function getModifierCallback(string $modifierName) { |
||
1577 | foreach ($this->getExtensions() as $extension) { |
||
1578 | if ($callback = $extension->getModifierCallback($modifierName)) { |
||
1579 | return [new CallbackWrapper($modifierName, $callback), 'handle']; |
||
1580 | } |
||
1581 | } |
||
1582 | return null; |
||
1583 | } |
||
1584 | |||
1585 | public function getFunctionHandler(string $functionName): ?\Smarty\FunctionHandler\FunctionHandlerInterface { |
||
1586 | foreach ($this->getExtensions() as $extension) { |
||
1587 | if ($handler = $extension->getFunctionHandler($functionName)) { |
||
1588 | return $handler; |
||
1589 | } |
||
1590 | } |
||
1591 | return null; |
||
1592 | } |
||
1593 | |||
1594 | public function getBlockHandler(string $blockTagName): ?\Smarty\BlockHandler\BlockHandlerInterface { |
||
1595 | foreach ($this->getExtensions() as $extension) { |
||
1596 | if ($handler = $extension->getBlockHandler($blockTagName)) { |
||
1597 | return $handler; |
||
1598 | } |
||
1599 | } |
||
1600 | return null; |
||
1601 | } |
||
1602 | |||
1603 | public function getModifierCompiler(string $modifier): ?\Smarty\Compile\Modifier\ModifierCompilerInterface { |
||
1604 | foreach ($this->getExtensions() as $extension) { |
||
1605 | if ($handler = $extension->getModifierCompiler($modifier)) { |
||
1606 | return $handler; |
||
1607 | } |
||
1608 | } |
||
1609 | return null; |
||
1610 | } |
||
1611 | |||
1612 | /** |
||
1613 | * Run pre-filters over template source |
||
1614 | * |
||
1615 | * @param string $source the content which shall be processed by the filters |
||
1616 | * @param Template $template template object |
||
1617 | * |
||
1618 | * @return string the filtered source |
||
1619 | */ |
||
1620 | public function runPreFilters($source, Template $template) { |
||
1621 | |||
1622 | foreach ($this->getExtensions() as $extension) { |
||
1623 | /** @var \Smarty\Filter\FilterInterface $filter */ |
||
1624 | foreach ($extension->getPreFilters() as $filter) { |
||
1625 | $source = $filter->filter($source, $template); |
||
1626 | } |
||
1627 | } |
||
1628 | |||
1629 | // return filtered output |
||
1630 | return $source; |
||
1631 | } |
||
1632 | |||
1633 | /** |
||
1634 | * Run post-filters over template's compiled code |
||
1635 | * |
||
1636 | * @param string $code the content which shall be processed by the filters |
||
1637 | * @param Template $template template object |
||
1638 | * |
||
1639 | * @return string the filtered code |
||
1640 | */ |
||
1641 | public function runPostFilters($code, Template $template) { |
||
1642 | |||
1643 | foreach ($this->getExtensions() as $extension) { |
||
1644 | /** @var \Smarty\Filter\FilterInterface $filter */ |
||
1645 | foreach ($extension->getPostFilters() as $filter) { |
||
1646 | $code = $filter->filter($code, $template); |
||
1647 | } |
||
1648 | } |
||
1649 | |||
1650 | // return filtered output |
||
1651 | return $code; |
||
1652 | } |
||
1653 | |||
1654 | /** |
||
1655 | * Run filters over template output |
||
1656 | * |
||
1657 | * @param string $content the content which shall be processed by the filters |
||
1658 | * @param Template $template template object |
||
1659 | * |
||
1660 | * @return string the filtered (modified) output |
||
1661 | */ |
||
1662 | public function runOutputFilters($content, Template $template) { |
||
1663 | |||
1664 | foreach ($this->getExtensions() as $extension) { |
||
1665 | /** @var \Smarty\Filter\FilterInterface $filter */ |
||
1666 | foreach ($extension->getOutputFilters() as $filter) { |
||
1667 | $content = $filter->filter($content, $template); |
||
1668 | } |
||
1669 | } |
||
1670 | |||
1671 | // return filtered output |
||
1672 | return $content; |
||
1673 | } |
||
1674 | |||
1675 | /** |
||
1676 | * Writes file in a safe way to disk |
||
1677 | * |
||
1678 | * @param string $_filepath complete filepath |
||
1679 | * @param string $_contents file content |
||
1680 | * |
||
1681 | * @return boolean true |
||
1682 | * @throws Exception |
||
1683 | */ |
||
1684 | public function writeFile($_filepath, $_contents) { |
||
1685 | $_error_reporting = error_reporting(); |
||
1686 | error_reporting($_error_reporting & ~E_NOTICE & ~E_WARNING); |
||
1687 | $_dirpath = dirname($_filepath); |
||
1688 | // if subdirs, create dir structure |
||
1689 | if ($_dirpath !== '.') { |
||
1690 | $i = 0; |
||
1691 | // loop if concurrency problem occurs |
||
1692 | // see https://bugs.php.net/bug.php?id=35326 |
||
1693 | while (!is_dir($_dirpath)) { |
||
1694 | if (@mkdir($_dirpath, 0777, true)) { |
||
1695 | break; |
||
1696 | } |
||
1697 | clearstatcache(); |
||
1698 | if (++$i === 3) { |
||
1699 | error_reporting($_error_reporting); |
||
1700 | throw new Exception("unable to create directory {$_dirpath}"); |
||
1701 | } |
||
1702 | sleep(1); |
||
1703 | } |
||
1704 | } |
||
1705 | // write to tmp file, then move to overt file lock race condition |
||
1706 | $_tmp_file = $_dirpath . DIRECTORY_SEPARATOR . str_replace(['.', ','], '_', uniqid('wrt', true)); |
||
1707 | if (!file_put_contents($_tmp_file, $_contents)) { |
||
1708 | error_reporting($_error_reporting); |
||
1709 | throw new Exception("unable to write file {$_tmp_file}"); |
||
1710 | } |
||
1711 | /* |
||
1712 | * Windows' rename() fails if the destination exists, |
||
1713 | * Linux' rename() properly handles the overwrite. |
||
1714 | * Simply unlink()ing a file might cause other processes |
||
1715 | * currently reading that file to fail, but linux' rename() |
||
1716 | * seems to be smart enough to handle that for us. |
||
1717 | */ |
||
1718 | if (\Smarty\Smarty::$_IS_WINDOWS) { |
||
1719 | // remove original file |
||
1720 | if (is_file($_filepath)) { |
||
1721 | @unlink($_filepath); |
||
1722 | } |
||
1723 | // rename tmp file |
||
1724 | $success = @rename($_tmp_file, $_filepath); |
||
1725 | } else { |
||
1726 | // rename tmp file |
||
1727 | $success = @rename($_tmp_file, $_filepath); |
||
1728 | if (!$success) { |
||
1729 | // remove original file |
||
1730 | if (is_file($_filepath)) { |
||
1731 | @unlink($_filepath); |
||
1732 | } |
||
1733 | // rename tmp file |
||
1734 | $success = @rename($_tmp_file, $_filepath); |
||
1735 | } |
||
1736 | } |
||
1737 | if (!$success) { |
||
1738 | error_reporting($_error_reporting); |
||
1739 | throw new Exception("unable to write file {$_filepath}"); |
||
1740 | } |
||
1741 | // set file permissions |
||
1742 | @chmod($_filepath, 0666 & ~umask()); |
||
1743 | error_reporting($_error_reporting); |
||
1744 | return true; |
||
1745 | } |
||
1746 | |||
1747 | private $runtimes = []; |
||
1748 | |||
1749 | /** |
||
1750 | * Loads and returns a runtime extension or null if not found |
||
1751 | * |
||
1752 | * @param string $type |
||
1753 | * |
||
1754 | * @return object|null |
||
1755 | */ |
||
1756 | public function getRuntime(string $type) { |
||
1779 | } |
||
1780 | |||
1781 | /** |
||
1782 | * Indicates if a runtime is available. |
||
1783 | * |
||
1784 | * @param string $type |
||
1785 | * |
||
1786 | * @return bool |
||
1787 | */ |
||
1788 | public function hasRuntime(string $type): bool { |
||
1789 | try { |
||
1790 | $this->getRuntime($type); |
||
1791 | return true; |
||
1792 | } catch (\Smarty\Exception $e) { |
||
1793 | return false; |
||
1794 | } |
||
1795 | } |
||
1796 | |||
1797 | /** |
||
1798 | * @return callable|null |
||
1799 | */ |
||
1800 | public function getDefaultPluginHandlerFunc(): ?callable { |
||
1801 | return $this->default_plugin_handler_func; |
||
1802 | } |
||
1803 | |||
1804 | /** |
||
1805 | * load a filter of specified type and name |
||
1806 | * |
||
1807 | * @param string $type filter type |
||
1808 | * @param string $name filter name |
||
1809 | * |
||
1810 | * @return bool |
||
1811 | * @throws \Smarty\Exception |
||
1812 | * @api Smarty::loadFilter() |
||
1813 | * |
||
1814 | * @deprecated since 5.0 |
||
1815 | */ |
||
1816 | public function loadFilter($type, $name) { |
||
1817 | |||
1818 | if ($type == \Smarty\Smarty::FILTER_VARIABLE) { |
||
1819 | foreach ($this->getExtensions() as $extension) { |
||
1820 | if ($extension->getModifierCallback($name)) { |
||
1821 | |||
1822 | trigger_error('Using Smarty::loadFilter() to load variable filters is deprecated and will ' . |
||
1823 | 'be removed in a future release. Use Smarty::addDefaultModifiers() to add a modifier.', |
||
1824 | E_USER_DEPRECATED); |
||
1825 | |||
1826 | $this->addDefaultModifiers([$name]); |
||
1827 | return true; |
||
1828 | } |
||
1829 | } |
||
1830 | } |
||
1831 | |||
1832 | trigger_error('Using Smarty::loadFilter() to load filters is deprecated and will be ' . |
||
1833 | 'removed in a future release. Use Smarty::addExtension() to add an extension or Smarty::registerFilter to ' . |
||
1834 | 'quickly register a filter using a callback function.', E_USER_DEPRECATED); |
||
1835 | |||
1836 | if ($type == \Smarty\Smarty::FILTER_OUTPUT && $name == 'trimwhitespace') { |
||
1837 | $this->BCPluginsAdapter->addOutputFilter(new TrimWhitespace()); |
||
1838 | return true; |
||
1839 | } |
||
1840 | |||
1841 | $_plugin = "smarty_{$type}filter_{$name}"; |
||
1842 | if (!is_callable($_plugin) && class_exists($_plugin, false)) { |
||
1843 | $_plugin = [$_plugin, 'execute']; |
||
1844 | } |
||
1845 | |||
1846 | if (is_callable($_plugin)) { |
||
1847 | $this->registerFilter($type, $_plugin, $name); |
||
1848 | return true; |
||
1849 | } |
||
1850 | |||
1851 | throw new Exception("{$type}filter '{$name}' not found or callable"); |
||
1852 | } |
||
1853 | |||
1854 | /** |
||
1855 | * load a filter of specified type and name |
||
1856 | * |
||
1857 | * @param string $type filter type |
||
1858 | * @param string $name filter name |
||
1859 | * |
||
1860 | * @return static |
||
1861 | * @throws \Smarty\Exception |
||
1862 | * @api Smarty::unloadFilter() |
||
1863 | * |
||
1864 | * |
||
1865 | * @deprecated since 5.0 |
||
1866 | */ |
||
1867 | public function unloadFilter($type, $name) { |
||
1868 | trigger_error('Using Smarty::unloadFilter() to unload filters is deprecated and will be ' . |
||
1869 | 'removed in a future release. Use Smarty::addExtension() to add an extension or Smarty::(un)registerFilter to ' . |
||
1870 | 'quickly (un)register a filter using a callback function.', E_USER_DEPRECATED); |
||
1871 | |||
1872 | return $this->unregisterFilter($type, $name); |
||
1873 | } |
||
1874 | |||
1875 | private $_caching_type = 'file'; |
||
1876 | |||
1877 | /** |
||
1878 | * @param $type |
||
1879 | * |
||
1880 | * @return void |
||
1881 | * @deprecated since 5.0 |
||
1882 | */ |
||
1883 | public function setCachingType($type) { |
||
1884 | trigger_error('Using Smarty::setCachingType() is deprecated and will be ' . |
||
1885 | 'removed in a future release. Use Smarty::setCacheResource() instead.', E_USER_DEPRECATED); |
||
1886 | $this->_caching_type = $type; |
||
1887 | $this->activateBCCacheResource(); |
||
1888 | } |
||
1889 | |||
1890 | /** |
||
1891 | * @return string |
||
1892 | * @deprecated since 5.0 |
||
1893 | */ |
||
1894 | public function getCachingType(): string { |
||
1895 | trigger_error('Using Smarty::getCachingType() is deprecated and will be ' . |
||
1896 | 'removed in a future release.', E_USER_DEPRECATED); |
||
1897 | return $this->_caching_type; |
||
1898 | } |
||
1899 | |||
1900 | /** |
||
1901 | * Registers a resource to fetch a template |
||
1902 | * |
||
1903 | * @param string $name name of resource type |
||
1904 | * @param Base $resource_handler |
||
1905 | * |
||
1906 | * @return static |
||
1907 | * |
||
1908 | * @api Smarty::registerCacheResource() |
||
1909 | * |
||
1910 | * @deprecated since 5.0 |
||
1911 | */ |
||
1912 | public function registerCacheResource($name, \Smarty\Cacheresource\Base $resource_handler) { |
||
1913 | |||
1914 | trigger_error('Using Smarty::registerCacheResource() is deprecated and will be ' . |
||
1915 | 'removed in a future release. Use Smarty::setCacheResource() instead.', E_USER_DEPRECATED); |
||
1916 | |||
1917 | $this->registered_cache_resources[$name] = $resource_handler; |
||
1918 | $this->activateBCCacheResource(); |
||
1919 | return $this; |
||
1920 | } |
||
1921 | |||
1922 | /** |
||
1923 | * Unregisters a resource to fetch a template |
||
1924 | * |
||
1925 | * @param $name |
||
1926 | * |
||
1927 | * @return static |
||
1928 | * @api Smarty::unregisterCacheResource() |
||
1929 | * |
||
1930 | * @deprecated since 5.0 |
||
1931 | * |
||
1932 | */ |
||
1933 | public function unregisterCacheResource($name) { |
||
1934 | |||
1935 | trigger_error('Using Smarty::unregisterCacheResource() is deprecated and will be ' . |
||
1936 | 'removed in a future release.', E_USER_DEPRECATED); |
||
1937 | |||
1938 | if (isset($this->registered_cache_resources[$name])) { |
||
1939 | unset($this->registered_cache_resources[$name]); |
||
1940 | } |
||
1941 | return $this; |
||
1942 | } |
||
1943 | |||
1944 | private function activateBCCacheResource() { |
||
1945 | if ($this->_caching_type == 'file') { |
||
1946 | $this->setCacheResource(new File()); |
||
1947 | } |
||
1948 | if (isset($this->registered_cache_resources[$this->_caching_type])) { |
||
1949 | $this->setCacheResource($this->registered_cache_resources[$this->_caching_type]); |
||
1950 | } |
||
1951 | } |
||
1952 | |||
1953 | /** |
||
1954 | * Registers a filter function |
||
1955 | * |
||
1956 | * @param string $type filter type |
||
1957 | * @param callable $callback |
||
1958 | * @param string|null $name optional filter name |
||
1959 | * |
||
1960 | * @return static |
||
1961 | * @throws \Smarty\Exception |
||
1962 | * |
||
1963 | * @api Smarty::registerFilter() |
||
1964 | */ |
||
1965 | public function registerFilter($type, $callback, $name = null) { |
||
1993 | } |
||
1994 | |||
1995 | /** |
||
1996 | * Return internal filter name |
||
1997 | * |
||
1998 | * @param callback $callable |
||
1999 | * |
||
2000 | * @return string|null internal filter name or null if callable cannot be serialized |
||
2001 | */ |
||
2002 | private function _getFilterName($callable) { |
||
2003 | if (is_array($callable)) { |
||
2004 | $_class_name = is_object($callable[0]) ? get_class($callable[0]) : $callable[0]; |
||
2005 | return $_class_name . '_' . $callable[1]; |
||
2006 | } elseif (is_string($callable)) { |
||
2007 | return $callable; |
||
2008 | } |
||
2009 | return null; |
||
2010 | } |
||
2011 | |||
2012 | /** |
||
2013 | * Unregisters a filter function. Smarty cannot unregister closures/anonymous functions if |
||
2014 | * no name was given in ::registerFilter. |
||
2015 | * |
||
2016 | * @param string $type filter type |
||
2017 | * @param callback|string $name the name previously used in ::registerFilter |
||
2018 | * |
||
2019 | * @return static |
||
2020 | * @throws \Smarty\Exception |
||
2021 | * @api Smarty::unregisterFilter() |
||
2022 | * |
||
2023 | * |
||
2024 | */ |
||
2025 | public function unregisterFilter($type, $name) { |
||
2026 | |||
2027 | if (!is_string($name)) { |
||
2028 | $name = $this->_getFilterName($name); |
||
2029 | } |
||
2030 | |||
2031 | if ($name) { |
||
2032 | switch ($type) { |
||
2033 | case 'output': |
||
2034 | $this->BCPluginsAdapter->removeOutputFilter($name); |
||
2035 | break; |
||
2036 | case 'pre': |
||
2037 | $this->BCPluginsAdapter->removePreFilter($name); |
||
2038 | break; |
||
2039 | case 'post': |
||
2040 | $this->BCPluginsAdapter->removePostFilter($name); |
||
2041 | break; |
||
2042 | default: |
||
2043 | throw new Exception("Illegal filter type '{$type}'"); |
||
2044 | } |
||
2045 | } |
||
2046 | |||
2047 | return $this; |
||
2048 | } |
||
2049 | |||
2050 | /** |
||
2051 | * Add default modifiers |
||
2052 | * |
||
2053 | * @param array|string $modifiers modifier or list of modifiers |
||
2054 | * to add |
||
2055 | * |
||
2056 | * @return static |
||
2057 | * @api Smarty::addDefaultModifiers() |
||
2058 | * |
||
2059 | */ |
||
2060 | public function addDefaultModifiers($modifiers) { |
||
2061 | if (is_array($modifiers)) { |
||
2062 | $this->default_modifiers = array_merge($this->default_modifiers, $modifiers); |
||
2063 | } else { |
||
2064 | $this->default_modifiers[] = $modifiers; |
||
2065 | } |
||
2066 | return $this; |
||
2067 | } |
||
2068 | |||
2069 | /** |
||
2070 | * Get default modifiers |
||
2071 | * |
||
2072 | * @return array list of default modifiers |
||
2073 | * @api Smarty::getDefaultModifiers() |
||
2074 | * |
||
2075 | */ |
||
2076 | public function getDefaultModifiers() { |
||
2077 | return $this->default_modifiers; |
||
2078 | } |
||
2079 | |||
2080 | /** |
||
2081 | * Set default modifiers |
||
2082 | * |
||
2083 | * @param array|string $modifiers modifier or list of modifiers |
||
2084 | * to set |
||
2085 | * |
||
2086 | * @return static |
||
2087 | * @api Smarty::setDefaultModifiers() |
||
2088 | * |
||
2089 | */ |
||
2090 | public function setDefaultModifiers($modifiers) { |
||
2091 | $this->default_modifiers = (array)$modifiers; |
||
2092 | return $this; |
||
2093 | } |
||
2094 | |||
2095 | /** |
||
2096 | * @return Cacheresource\Base |
||
2097 | */ |
||
2098 | public function getCacheResource(): Cacheresource\Base { |
||
2099 | return $this->cacheResource; |
||
2100 | } |
||
2101 | |||
2102 | /** |
||
2103 | * @param Cacheresource\Base $cacheResource |
||
2104 | */ |
||
2105 | public function setCacheResource(Cacheresource\Base $cacheResource): void { |
||
2107 | } |
||
2108 | |||
2109 | /** |
||
2110 | * fetches a rendered Smarty template |
||
2111 | * |
||
2112 | * @param string $template the resource handle of the template file or template object |
||
2113 | * @param mixed $cache_id cache id to be used with this template |
||
2114 | * @param mixed $compile_id compile id to be used with this template |
||
2115 | * |
||
2116 | * @return string rendered template output |
||
2117 | * @throws Exception |
||
2118 | * @throws Exception |
||
2119 | */ |
||
2120 | public function fetch($template = null, $cache_id = null, $compile_id = null) { |
||
2121 | return $this->returnOrCreateTemplate($template, $cache_id, $compile_id)->fetch(); |
||
2122 | } |
||
2123 | |||
2124 | /** |
||
2125 | * displays a Smarty template |
||
2126 | * |
||
2127 | * @param string $template the resource handle of the template file or template object |
||
2128 | * @param mixed $cache_id cache id to be used with this template |
||
2129 | * @param mixed $compile_id compile id to be used with this template |
||
2130 | * |
||
2131 | * @throws \Exception |
||
2132 | * @throws \Smarty\Exception |
||
2133 | */ |
||
2134 | public function display($template = null, $cache_id = null, $compile_id = null) { |
||
2135 | $this->returnOrCreateTemplate($template, $cache_id, $compile_id)->display(); |
||
2136 | } |
||
2137 | |||
2138 | /** |
||
2139 | * @param $resource_name |
||
2140 | * @param $cache_id |
||
2141 | * @param $compile_id |
||
2142 | * @param $parent |
||
2143 | * @param $caching |
||
2144 | * @param $cache_lifetime |
||
2145 | * @param bool $isConfig |
||
2146 | * @param array $data |
||
2147 | * |
||
2148 | * @return Template |
||
2149 | * @throws Exception |
||
2150 | */ |
||
2151 | public function doCreateTemplate( |
||
2192 | } |
||
2193 | |||
2194 | /** |
||
2195 | * test if cache is valid |
||
2196 | * |
||
2197 | * @param null|string|Template $template the resource handle of the template file or template |
||
2198 | * object |
||
2199 | * @param mixed $cache_id cache id to be used with this template |
||
2200 | * @param mixed $compile_id compile id to be used with this template |
||
2201 | * |
||
2202 | * @return bool cache status |
||
2203 | * @throws \Exception |
||
2204 | * @throws \Smarty\Exception |
||
2205 | * |
||
2206 | * @api Smarty::isCached() |
||
2207 | */ |
||
2208 | public function isCached($template = null, $cache_id = null, $compile_id = null) { |
||
2209 | return $this->returnOrCreateTemplate($template, $cache_id, $compile_id)->isCached(); |
||
2210 | } |
||
2211 | |||
2212 | /** |
||
2213 | * @param $template |
||
2214 | * @param $cache_id |
||
2215 | * @param $compile_id |
||
2216 | * @param $parent |
||
2217 | * |
||
2218 | * @return Template |
||
2219 | * @throws Exception |
||
2220 | */ |
||
2221 | private function returnOrCreateTemplate($template, $cache_id = null, $compile_id = null) { |
||
2227 | } |
||
2228 | |||
2229 | /** |
||
2230 | * Sets if Smarty should check If-Modified-Since headers to determine cache validity. |
||
2231 | * @param bool $cache_modified_check |
||
2232 | * @return void |
||
2233 | */ |
||
2234 | public function setCacheModifiedCheck($cache_modified_check): void { |
||
2235 | $this->cache_modified_check = (bool) $cache_modified_check; |
||
2236 | } |
||
2237 | |||
2238 | } |
||
2239 | |||
2240 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.