Completed
Branch master (e379bd)
by Pierre-Henry
33:06
created

Smarty::_getTemplateId()   C

Complexity

Conditions 10
Paths 64

Size

Total Lines 21
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 16
nc 64
nop 5
dl 0
loc 21
rs 6.6746
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 38 and the first side effect is on line 72.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Project:     Smarty: the PHP compiling template engine
4
 * File:        Smarty.class.php
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 * For questions, help, comments, discussion, etc., please join the
20
 * Smarty mailing list. Send a blank e-mail to
21
 * [email protected]
22
 *
23
 * @link      http://www.smarty.net/
24
 * @copyright 2016 New Digital Group, Inc.
25
 * @copyright 2016 Uwe Tews
26
 * @author    Monte Ohrt <monte at ohrt dot com>
27
 * @author    Uwe Tews
28
 * @author    Rodney Rehm
29
 * @package   Smarty
30
 * @version   3.1.31
31
 */
32
33
/**
34
 * set SMARTY_DIR to absolute path to Smarty library files.
35
 * Sets SMARTY_DIR only if user application has not already defined it.
36
 */
37
if (!defined('SMARTY_DIR')) {
38
    define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
39
}
40
41
/**
42
 * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins.
43
 * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it.
44
 */
45
if (!defined('SMARTY_SYSPLUGINS_DIR')) {
46
    define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DIRECTORY_SEPARATOR);
47
}
48
if (!defined('SMARTY_PLUGINS_DIR')) {
49
    define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DIRECTORY_SEPARATOR);
50
}
51
if (!defined('SMARTY_MBSTRING')) {
52
    define('SMARTY_MBSTRING', function_exists('mb_get_info'));
53
}
54
if (!defined('SMARTY_RESOURCE_CHAR_SET')) {
55
    // UTF-8 can only be done properly when mbstring is available!
56
    /**
57
     * @deprecated in favor of Smarty::$_CHARSET
58
     */
59
    define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1');
60
}
61
if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) {
62
    /**
63
     * @deprecated in favor of Smarty::$_DATE_FORMAT
64
     */
65
    define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y');
66
}
67
68
/**
69
 * Load Smarty_Autoloader
70
 */
71
if (!class_exists('Smarty_Autoloader')) {
72
    include __DIR__ . '/bootstrap.php';
73
}
74
75
/**
76
 * Load always needed external class files
77
 */
78
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php';
79
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_extension_handler.php';
80
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php';
81
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php';
82
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php';
83
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_variable.php';
84
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_source.php';
85
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_resource_base.php';
86
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_resource_file.php';
87
88
/**
89
 * This is the main Smarty class
90
 *
91
 * @package Smarty
92
 *
93
 * The following methods will be dynamically loaded by the extension handler when they are called.
94
 * They are located in a corresponding Smarty_Internal_Method_xxxx class
95
 *
96
 * @method int clearAllCache(int $exp_time = null, string $type = null)
97
 * @method int clearCache(string $template_name, string $cache_id = null, string $compile_id = null, int $exp_time = null, string $type = null)
98
 * @method int compileAllTemplates(string $extension = '.tpl', bool $force_compile = false, int $time_limit = 0, int $max_errors = null)
99
 * @method int compileAllConfig(string $extension = '.conf', bool $force_compile = false, int $time_limit = 0, int $max_errors = null)
100
 * @method int clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
101
 */
102
class Smarty extends Smarty_Internal_TemplateBase
103
{
104
    /**#@+
105
     * constant definitions
106
     */
107
108
    /**
109
     * smarty version
110
     */
111
    const SMARTY_VERSION = '3.1.31';
112
113
    /**
114
     * define variable scopes
115
     */
116
    const SCOPE_LOCAL = 1;
117
118
    const SCOPE_PARENT = 2;
119
120
    const SCOPE_TPL_ROOT = 4;
121
122
    const SCOPE_ROOT = 8;
123
124
    const SCOPE_SMARTY = 16;
125
126
    const SCOPE_GLOBAL = 32;
127
128
    /**
129
     * define caching modes
130
     */
131
    const CACHING_OFF = 0;
132
133
    const CACHING_LIFETIME_CURRENT = 1;
134
135
    const CACHING_LIFETIME_SAVED = 2;
136
137
    /**
138
     * define constant for clearing cache files be saved expiration dates
139
     */
140
    const CLEAR_EXPIRED = - 1;
141
142
    /**
143
     * define compile check modes
144
     */
145
    const COMPILECHECK_OFF = 0;
146
147
    const COMPILECHECK_ON = 1;
148
149
    const COMPILECHECK_CACHEMISS = 2;
150
151
    /**
152
     * define debug modes
153
     */
154
    const DEBUG_OFF = 0;
155
156
    const DEBUG_ON = 1;
157
158
    const DEBUG_INDIVIDUAL = 2;
159
160
    /**
161
     * modes for handling of "<?php ... ?>" tags in templates.
162
     */
163
    const PHP_PASSTHRU = 0; //-> print tags as plain text
164
165
    const PHP_QUOTE = 1; //-> escape tags as entities
166
167
    const PHP_REMOVE = 2; //-> escape tags as entities
168
169
    const PHP_ALLOW = 3; //-> escape tags as entities
170
171
    /**
172
     * filter types
173
     */
174
    const FILTER_POST = 'post';
175
176
    const FILTER_PRE = 'pre';
177
178
    const FILTER_OUTPUT = 'output';
179
180
    const FILTER_VARIABLE = 'variable';
181
182
    /**
183
     * plugin types
184
     */
185
    const PLUGIN_FUNCTION = 'function';
186
187
    const PLUGIN_BLOCK = 'block';
188
189
    const PLUGIN_COMPILER = 'compiler';
190
191
    const PLUGIN_MODIFIER = 'modifier';
192
193
    const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler';
194
195
    /**
196
     * Resource caching modes
197
     * (not used since 3.1.30)
198
     */
199
    const RESOURCE_CACHE_OFF = 0;
200
201
    const RESOURCE_CACHE_AUTOMATIC = 1; // cache template objects by rules
202
203
    const RESOURCE_CACHE_TEMPLATE = 2; // cache all template objects
204
205
    const RESOURCE_CACHE_ON = 4;    // cache source and compiled resources
206
207
    /**#@-*/
208
209
    /**
210
     * assigned global tpl vars
211
     */
212
    public static $global_tpl_vars = array();
213
214
    /**
215
     * error handler returned by set_error_handler() in Smarty::muteExpectedErrors()
216
     */
217
    public static $_previous_error_handler = null;
218
219
    /**
220
     * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors()
221
     */
222
    public static $_muted_directories = array();
223
224
    /**
225
     * Flag denoting if Multibyte String functions are available
226
     */
227
    public static $_MBSTRING = SMARTY_MBSTRING;
228
229
    /**
230
     * The character set to adhere to (e.g. "UTF-8")
231
     */
232
    public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET;
0 ignored issues
show
Deprecated Code introduced by
The constant SMARTY_RESOURCE_CHAR_SET has been deprecated with message: in favor of Smarty::$_CHARSET

This class constant has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
233
234
    /**
235
     * The date format to be used internally
236
     * (accepts date() and strftime())
237
     */
238
    public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT;
0 ignored issues
show
Deprecated Code introduced by
The constant SMARTY_RESOURCE_DATE_FORMAT has been deprecated with message: in favor of Smarty::$_DATE_FORMAT

This class constant has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
239
240
    /**
241
     * Flag denoting if PCRE should run in UTF-8 mode
242
     */
243
    public static $_UTF8_MODIFIER = 'u';
244
245
    /**
246
     * Flag denoting if operating system is windows
247
     */
248
    public static $_IS_WINDOWS = false;
249
250
    /**#@+
251
     * variables
252
     */
253
254
    /**
255
     * auto literal on delimiters with whitespace
256
     *
257
     * @var boolean
258
     */
259
    public $auto_literal = true;
260
261
    /**
262
     * display error on not assigned variables
263
     *
264
     * @var boolean
265
     */
266
    public $error_unassigned = false;
267
268
    /**
269
     * look up relative file path in include_path
270
     *
271
     * @var boolean
272
     */
273
    public $use_include_path = false;
274
275
    /**
276
     * template directory
277
     *
278
     * @var array
279
     */
280
    protected $template_dir = array('./templates/');
281
282
    /**
283
     * flags for normalized template directory entries
284
     *
285
     * @var array
286
     */
287
    protected $_processedTemplateDir = array();
288
289
    /**
290
     * flag if template_dir is normalized
291
     *
292
     * @var bool
293
     */
294
    public $_templateDirNormalized = false;
295
296
    /**
297
     * joined template directory string used in cache keys
298
     *
299
     * @var string
300
     */
301
    public $_joined_template_dir = null;
302
303
    /**
304
     * config directory
305
     *
306
     * @var array
307
     */
308
    protected $config_dir = array('./configs/');
309
310
    /**
311
     * flags for normalized template directory entries
312
     *
313
     * @var array
314
     */
315
    protected $_processedConfigDir = array();
316
317
    /**
318
     * flag if config_dir is normalized
319
     *
320
     * @var bool
321
     */
322
    public $_configDirNormalized = false;
323
324
    /**
325
     * joined config directory string used in cache keys
326
     *
327
     * @var string
328
     */
329
    public $_joined_config_dir = null;
330
331
    /**
332
     * default template handler
333
     *
334
     * @var callable
335
     */
336
    public $default_template_handler_func = null;
337
338
    /**
339
     * default config handler
340
     *
341
     * @var callable
342
     */
343
    public $default_config_handler_func = null;
344
345
    /**
346
     * default plugin handler
347
     *
348
     * @var callable
349
     */
350
    public $default_plugin_handler_func = null;
351
352
    /**
353
     * compile directory
354
     *
355
     * @var string
356
     */
357
    protected $compile_dir = './templates_c/';
358
359
    /**
360
     * flag if template_dir is normalized
361
     *
362
     * @var bool
363
     */
364
    public $_compileDirNormalized = false;
365
366
    /**
367
     * plugins directory
368
     *
369
     * @var array
370
     */
371
    protected $plugins_dir = array();
372
373
    /**
374
     * flag if plugins_dir is normalized
375
     *
376
     * @var bool
377
     */
378
    public $_pluginsDirNormalized = false;
379
380
    /**
381
     * cache directory
382
     *
383
     * @var string
384
     */
385
    protected $cache_dir = './cache/';
386
387
    /**
388
     * flag if template_dir is normalized
389
     *
390
     * @var bool
391
     */
392
    public $_cacheDirNormalized = false;
393
394
    /**
395
     * force template compiling?
396
     *
397
     * @var boolean
398
     */
399
    public $force_compile = false;
400
401
    /**
402
     * check template for modifications?
403
     *
404
     * @var boolean
405
     */
406
    public $compile_check = true;
407
408
    /**
409
     * use sub dirs for compiled/cached files?
410
     *
411
     * @var boolean
412
     */
413
    public $use_sub_dirs = false;
414
415
    /**
416
     * allow ambiguous resources (that are made unique by the resource handler)
417
     *
418
     * @var boolean
419
     */
420
    public $allow_ambiguous_resources = false;
421
422
    /**
423
     * merge compiled includes
424
     *
425
     * @var boolean
426
     */
427
    public $merge_compiled_includes = false;
428
429
    /*
430
    * flag for behaviour when extends: resource  and {extends} tag are used simultaneous
431
    *   if false disable execution of {extends} in templates called by extends resource.
432
    *   (behaviour as versions < 3.1.28)
433
    *
434
    * @var boolean
435
    */
436
    public $extends_recursion = true;
437
438
    /**
439
     * force cache file creation
440
     *
441
     * @var boolean
442
     */
443
    public $force_cache = false;
444
445
    /**
446
     * template left-delimiter
447
     *
448
     * @var string
449
     */
450
    public $left_delimiter = "{";
451
452
    /**
453
     * template right-delimiter
454
     *
455
     * @var string
456
     */
457
    public $right_delimiter = "}";
458
459
    /**#@+
460
     * security
461
     */
462
    /**
463
     * class name
464
     * This should be instance of Smarty_Security.
465
     *
466
     * @var string
467
     * @see Smarty_Security
468
     */
469
    public $security_class = 'Smarty_Security';
470
471
    /**
472
     * implementation of security class
473
     *
474
     * @var Smarty_Security
475
     */
476
    public $security_policy = null;
477
478
    /**
479
     * controls handling of PHP-blocks
480
     *
481
     * @var integer
482
     */
483
    public $php_handling = self::PHP_PASSTHRU;
484
485
    /**
486
     * controls if the php template file resource is allowed
487
     *
488
     * @var bool
489
     */
490
    public $allow_php_templates = false;
491
492
    /**#@-*/
493
    /**
494
     * debug mode
495
     * Setting this to true enables the debug-console.
496
     *
497
     * @var boolean
498
     */
499
    public $debugging = false;
500
501
    /**
502
     * This determines if debugging is enable-able from the browser.
503
     * <ul>
504
     *  <li>NONE => no debugging control allowed</li>
505
     *  <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
506
     * </ul>
507
     *
508
     * @var string
509
     */
510
    public $debugging_ctrl = 'NONE';
511
512
    /**
513
     * Name of debugging URL-param.
514
     * Only used when $debugging_ctrl is set to 'URL'.
515
     * The name of the URL-parameter that activates debugging.
516
     *
517
     * @var string
518
     */
519
    public $smarty_debug_id = 'SMARTY_DEBUG';
520
521
    /**
522
     * Path of debug template.
523
     *
524
     * @var string
525
     */
526
    public $debug_tpl = null;
527
528
    /**
529
     * When set, smarty uses this value as error_reporting-level.
530
     *
531
     * @var int
532
     */
533
    public $error_reporting = null;
534
535
    /**#@+
536
     * config var settings
537
     */
538
539
    /**
540
     * Controls whether variables with the same name overwrite each other.
541
     *
542
     * @var boolean
543
     */
544
    public $config_overwrite = true;
545
546
    /**
547
     * Controls whether config values of on/true/yes and off/false/no get converted to boolean.
548
     *
549
     * @var boolean
550
     */
551
    public $config_booleanize = true;
552
553
    /**
554
     * Controls whether hidden config sections/vars are read from the file.
555
     *
556
     * @var boolean
557
     */
558
    public $config_read_hidden = false;
559
560
    /**#@-*/
561
562
    /**#@+
563
     * resource locking
564
     */
565
566
    /**
567
     * locking concurrent compiles
568
     *
569
     * @var boolean
570
     */
571
    public $compile_locking = true;
572
573
    /**
574
     * Controls whether cache resources should use locking mechanism
575
     *
576
     * @var boolean
577
     */
578
    public $cache_locking = false;
579
580
    /**
581
     * seconds to wait for acquiring a lock before ignoring the write lock
582
     *
583
     * @var float
584
     */
585
    public $locking_timeout = 10;
586
587
    /**#@-*/
588
589
    /**
590
     * resource type used if none given
591
     * Must be an valid key of $registered_resources.
592
     *
593
     * @var string
594
     */
595
    public $default_resource_type = 'file';
596
597
    /**
598
     * caching type
599
     * Must be an element of $cache_resource_types.
600
     *
601
     * @var string
602
     */
603
    public $caching_type = 'file';
604
605
    /**
606
     * config type
607
     *
608
     * @var string
609
     */
610
    public $default_config_type = 'file';
611
612
    /**
613
     * check If-Modified-Since headers
614
     *
615
     * @var boolean
616
     */
617
    public $cache_modified_check = false;
618
619
    /**
620
     * registered plugins
621
     *
622
     * @var array
623
     */
624
    public $registered_plugins = array();
625
626
    /**
627
     * registered objects
628
     *
629
     * @var array
630
     */
631
    public $registered_objects = array();
632
633
    /**
634
     * registered classes
635
     *
636
     * @var array
637
     */
638
    public $registered_classes = array();
639
640
    /**
641
     * registered filters
642
     *
643
     * @var array
644
     */
645
    public $registered_filters = array();
646
647
    /**
648
     * registered resources
649
     *
650
     * @var array
651
     */
652
    public $registered_resources = array();
653
654
    /**
655
     * registered cache resources
656
     *
657
     * @var array
658
     */
659
    public $registered_cache_resources = array();
660
661
    /**
662
     * autoload filter
663
     *
664
     * @var array
665
     */
666
    public $autoload_filters = array();
667
668
    /**
669
     * default modifier
670
     *
671
     * @var array
672
     */
673
    public $default_modifiers = array();
674
675
    /**
676
     * autoescape variable output
677
     *
678
     * @var boolean
679
     */
680
    public $escape_html = false;
681
682
    /**
683
     * start time for execution time calculation
684
     *
685
     * @var int
686
     */
687
    public $start_time = 0;
688
689
    /**
690
     * required by the compiler for BC
691
     *
692
     * @var string
693
     */
694
    public $_current_file = null;
695
696
    /**
697
     * internal flag to enable parser debugging
698
     *
699
     * @var bool
700
     */
701
    public $_parserdebug = false;
702
703
    /**
704
     * This object type (Smarty = 1, template = 2, data = 4)
705
     *
706
     * @var int
707
     */
708
    public $_objType = 1;
709
710
    /**
711
     * Debug object
712
     *
713
     * @var Smarty_Internal_Debug
714
     */
715
    public $_debug = null;
716
717
    /**
718
     * Directory separator
719
     *
720
     * @var string
721
     */
722
    public $ds = DIRECTORY_SEPARATOR;
723
724
    /**
725
     * removed properties
726
     *
727
     * @var string[]
728
     */
729
    private $obsoleteProperties = array('resource_caching', 'template_resource_caching', 'direct_access_security',
730
                                        '_dir_perms', '_file_perms', 'plugin_search_order',
731
                                        'inheritance_merge_compiled_includes', 'resource_cache_mode',);
732
733
    /**
734
     * List of private properties which will call getter/setter on a direct access
735
     *
736
     * @var string[]
737
     */
738
    private $accessMap = array('template_dir' => 'TemplateDir', 'config_dir' => 'ConfigDir',
739
                               'plugins_dir' => 'PluginsDir', 'compile_dir' => 'CompileDir',
740
                               'cache_dir' => 'CacheDir',);
741
742
    /**#@-*/
743
744
    /**
745
     * Initialize new Smarty object
746
     */
747
    public function __construct()
0 ignored issues
show
Coding Style introduced by
__construct uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
748
    {
749
        $this->_clearTemplateCache();
750
        parent::__construct();
751
        if (is_callable('mb_internal_encoding')) {
752
            mb_internal_encoding(Smarty::$_CHARSET);
753
        }
754
        $this->start_time = microtime(true);
0 ignored issues
show
Documentation Bug introduced by
The property $start_time was declared of type integer, but microtime(true) is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
755
756
        if (isset($_SERVER[ 'SCRIPT_NAME' ])) {
757
            Smarty::$global_tpl_vars[ 'SCRIPT_NAME' ] = new Smarty_Variable($_SERVER[ 'SCRIPT_NAME' ]);
758
        }
759
760
        // Check if we're running on windows
761
        Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
762
        // let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8
763
        if (Smarty::$_CHARSET !== 'UTF-8') {
764
            Smarty::$_UTF8_MODIFIER = '';
765
        }
766
    }
767
768
    /**
769
     * Check if a template resource exists
770
     *
771
     * @param  string $resource_name template name
772
     *
773
     * @return boolean status
774
     */
775
    public function templateExists($resource_name)
776
    {
777
        // create source object
778
        $source = Smarty_Template_Source::load(null, $this, $resource_name);
779
        return $source->exists;
780
    }
781
782
    /**
783
     * Loads security class and enables security
784
     *
785
     * @param  string|Smarty_Security $security_class if a string is used, it must be class-name
786
     *
787
     * @return Smarty                 current Smarty instance for chaining
788
     * @throws SmartyException        when an invalid class name is provided
789
     */
790
    public function enableSecurity($security_class = null)
791
    {
792
        Smarty_Security::enableSecurity($this, $security_class);
0 ignored issues
show
Bug introduced by
It seems like $security_class defined by parameter $security_class on line 790 can also be of type null; however, Smarty_Security::enableSecurity() does only seem to accept string|object<Smarty_Security>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
793
        return $this;
794
    }
795
796
    /**
797
     * Disable security
798
     *
799
     * @return Smarty current Smarty instance for chaining
800
     */
801
    public function disableSecurity()
802
    {
803
        $this->security_policy = null;
804
805
        return $this;
806
    }
807
808
    /**
809
     * Set template directory
810
     *
811
     * @param  string|array $template_dir directory(s) of template sources
812
     * @param bool          $isConfig     true for config_dir
813
     *
814
     * @return \Smarty current Smarty instance for chaining
815
     */
816
    public function setTemplateDir($template_dir, $isConfig = false)
817
    {
818
        if ($isConfig) {
819
            $this->config_dir = array();
820
            $this->_processedConfigDir = array();
821
        } else {
822
            $this->template_dir = array();
823
            $this->_processedTemplateDir = array();
824
        }
825
        $this->addTemplateDir($template_dir, null, $isConfig);
826
        return $this;
827
    }
828
829
    /**
830
     * Add template directory(s)
831
     *
832
     * @param  string|array $template_dir directory(s) of template sources
833
     * @param  string       $key          of the array element to assign the template dir to
834
     * @param bool          $isConfig     true for config_dir
835
     *
836
     * @return Smarty          current Smarty instance for chaining
837
     */
838
    public function addTemplateDir($template_dir, $key = null, $isConfig = false)
839
    {
840
        if ($isConfig) {
841
            $processed = &$this->_processedConfigDir;
842
            $dir = &$this->config_dir;
843
            $this->_configDirNormalized = false;
844
        } else {
845
            $processed = &$this->_processedTemplateDir;
846
            $dir = &$this->template_dir;
847
            $this->_templateDirNormalized = false;
848
        }
849
        if (is_array($template_dir)) {
850
            foreach ($template_dir as $k => $v) {
851
                if (is_int($k)) {
852
                    // indexes are not merged but appended
853
                    $dir[] = $v;
854
                } else {
855
                    // string indexes are overridden
856
                    $dir[ $k ] = $v;
857
                    unset($processed[ $key ]);
858
                }
859
            }
860
        } else {
861
            if ($key !== null) {
862
                // override directory at specified index
863
                $dir[ $key ] = $template_dir;
864
                unset($processed[ $key ]);
865
            } else {
866
                // append new directory
867
                $dir[] = $template_dir;
868
            }
869
        }
870
        return $this;
871
    }
872
873
    /**
874
     * Get template directories
875
     *
876
     * @param mixed $index    index of directory to get, null to get all
877
     * @param bool  $isConfig true for config_dir
878
     *
879
     * @return array list of template directories, or directory of $index
880
     */
881
    public function getTemplateDir($index = null, $isConfig = false)
882
    {
883
        if ($isConfig) {
884
            $dir = &$this->config_dir;
885
        } else {
886
            $dir = &$this->template_dir;
887
        }
888
        if ($isConfig ? !$this->_configDirNormalized : !$this->_templateDirNormalized) {
889
            $this->_nomalizeTemplateConfig($isConfig);
890
        }
891
        if ($index !== null) {
892
            return isset($dir[ $index ]) ? $dir[ $index ] : null;
893
        }
894
        return $dir;
895
    }
896
897
    /**
898
     * Set config directory
899
     *
900
     * @param $config_dir
901
     *
902
     * @return Smarty       current Smarty instance for chaining
903
     */
904
    public function setConfigDir($config_dir)
905
    {
906
        return $this->setTemplateDir($config_dir, true);
907
    }
908
909
    /**
910
     * Add config directory(s)
911
     *
912
     * @param string|array $config_dir directory(s) of config sources
913
     * @param mixed        $key        key of the array element to assign the config dir to
914
     *
915
     * @return Smarty current Smarty instance for chaining
916
     */
917
    public function addConfigDir($config_dir, $key = null)
918
    {
919
        return $this->addTemplateDir($config_dir, $key, true);
920
    }
921
922
    /**
923
     * Get config directory
924
     *
925
     * @param mixed $index index of directory to get, null to get all
926
     *
927
     * @return array configuration directory
928
     */
929
    public function getConfigDir($index = null)
930
    {
931
        return $this->getTemplateDir($index, true);
932
    }
933
934
    /**
935
     * Set plugins directory
936
     *
937
     * @param  string|array $plugins_dir directory(s) of plugins
938
     *
939
     * @return Smarty       current Smarty instance for chaining
940
     */
941
    public function setPluginsDir($plugins_dir)
942
    {
943
        $this->plugins_dir = (array) $plugins_dir;
944
        $this->_pluginsDirNormalized = false;
945
        return $this;
946
    }
947
948
    /**
949
     * Adds directory of plugin files
950
     *
951
     * @param null|array $plugins_dir
952
     *
953
     * @return Smarty current Smarty instance for chaining
954
     */
955
    public function addPluginsDir($plugins_dir)
956
    {
957
        if (empty($this->plugins_dir)) {
958
            $this->plugins_dir[] = SMARTY_PLUGINS_DIR;
959
        }
960
        $this->plugins_dir = array_merge($this->plugins_dir, (array) $plugins_dir);
961
        $this->_pluginsDirNormalized = false;
962
        return $this;
963
    }
964
965
    /**
966
     * Get plugin directories
967
     *
968
     * @return array list of plugin directories
969
     */
970
    public function getPluginsDir()
971
    {
972
        if (empty($this->plugins_dir)) {
973
            $this->plugins_dir[] = SMARTY_PLUGINS_DIR;
974
            $this->_pluginsDirNormalized = false;
975
        }
976
        if (!$this->_pluginsDirNormalized) {
977
            if (!is_array($this->plugins_dir)) {
978
                $this->plugins_dir = (array) $this->plugins_dir;
979
            }
980
            foreach ($this->plugins_dir as $k => $v) {
981
                $this->plugins_dir[ $k ] = $this->_realpath(rtrim($v, "/\\") . $this->ds, true);
982
            }
983
            $this->_cache[ 'plugin_files' ] = array();
984
            $this->_pluginsDirNormalized = true;
985
        }
986
        return $this->plugins_dir;
987
    }
988
989
    /**
990
     *
991
     * @param  string $compile_dir directory to store compiled templates in
992
     *
993
     * @return Smarty current Smarty instance for chaining
994
     */
995
    public function setCompileDir($compile_dir)
996
    {
997
        $this->_normalizeDir('compile_dir', $compile_dir);
998
        $this->_compileDirNormalized = true;
999
        return $this;
1000
    }
1001
1002
    /**
1003
     * Get compiled directory
1004
     *
1005
     * @return string path to compiled templates
1006
     */
1007
    public function getCompileDir()
1008
    {
1009
        if (!$this->_compileDirNormalized) {
1010
            $this->_normalizeDir('compile_dir', $this->compile_dir);
1011
            $this->_compileDirNormalized = true;
1012
        }
1013
        return $this->compile_dir;
1014
    }
1015
1016
    /**
1017
     * Set cache directory
1018
     *
1019
     * @param  string $cache_dir directory to store cached templates in
1020
     *
1021
     * @return Smarty current Smarty instance for chaining
1022
     */
1023
    public function setCacheDir($cache_dir)
1024
    {
1025
        $this->_normalizeDir('cache_dir', $cache_dir);
1026
        $this->_cacheDirNormalized = true;
1027
        return $this;
1028
    }
1029
1030
    /**
1031
     * Get cache directory
1032
     *
1033
     * @return string path of cache directory
1034
     */
1035
    public function getCacheDir()
1036
    {
1037
        if (!$this->_cacheDirNormalized) {
1038
            $this->_normalizeDir('cache_dir', $this->cache_dir);
1039
            $this->_cacheDirNormalized = true;
1040
        }
1041
        return $this->cache_dir;
1042
    }
1043
1044
    /**
1045
     * Normalize and set directory string
1046
     *
1047
     * @param string $dirName cache_dir or compile_dir
1048
     * @param string $dir     filepath of folder
1049
     */
1050
    private function _normalizeDir($dirName, $dir)
1051
    {
1052
        $this->{$dirName} = $this->_realpath(rtrim($dir, "/\\") . $this->ds, true);
1053
        if (!isset(Smarty::$_muted_directories[ $this->{$dirName} ])) {
1054
            Smarty::$_muted_directories[ $this->{$dirName} ] = null;
1055
        }
1056
    }
1057
1058
    /**
1059
     * Normalize template_dir or config_dir
1060
     *
1061
     * @param bool $isConfig true for config_dir
1062
     *
1063
     */
1064
    private function _nomalizeTemplateConfig($isConfig)
1065
    {
1066
        if ($isConfig) {
1067
            $processed = &$this->_processedConfigDir;
1068
            $dir = &$this->config_dir;
1069
        } else {
1070
            $processed = &$this->_processedTemplateDir;
1071
            $dir = &$this->template_dir;
1072
        }
1073
        if (!is_array($dir)) {
1074
            $dir = (array) $dir;
1075
        }
1076
        foreach ($dir as $k => $v) {
1077
            if (!isset($processed[ $k ])) {
1078
                $dir[ $k ] = $v = $this->_realpath(rtrim($v, "/\\") . $this->ds, true);
1079
                $processed[ $k ] = true;
1080
            }
1081
        }
1082
        $isConfig ? $this->_configDirNormalized = true : $this->_templateDirNormalized = true;
1083
        $isConfig ? $this->_joined_config_dir = join('#', $this->config_dir) :
1084
            $this->_joined_template_dir = join('#', $this->template_dir);
1085
    }
1086
1087
    /**
1088
     * creates a template object
1089
     *
1090
     * @param  string  $template   the resource handle of the template file
1091
     * @param  mixed   $cache_id   cache id to be used with this template
1092
     * @param  mixed   $compile_id compile id to be used with this template
1093
     * @param  object  $parent     next higher level of Smarty variables
1094
     * @param  boolean $do_clone   flag is Smarty object shall be cloned
1095
     *
1096
     * @return object  template object
1097
     */
1098
    public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true)
1099
    {
1100
        if ($cache_id !== null && (is_object($cache_id) || is_array($cache_id))) {
1101
            $parent = $cache_id;
1102
            $cache_id = null;
1103
        }
1104
        if ($parent !== null && is_array($parent)) {
1105
            $data = $parent;
1106
            $parent = null;
1107
        } else {
1108
            $data = null;
1109
        }
1110
        if (!$this->_templateDirNormalized) {
1111
            $this->_nomalizeTemplateConfig(false);
1112
        }
1113
        $_templateId = $this->_getTemplateId($template, $cache_id, $compile_id);
1114
        $tpl = null;
0 ignored issues
show
Unused Code introduced by
$tpl is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1115
        if ($this->caching && isset(Smarty_Internal_Template::$isCacheTplObj[ $_templateId ])) {
1116
            $tpl = $do_clone ? clone Smarty_Internal_Template::$isCacheTplObj[ $_templateId ] :
1117
                Smarty_Internal_Template::$isCacheTplObj[ $_templateId ];
1118
            $tpl->inheritance = null;
1119
            $tpl->tpl_vars = $tpl->config_vars = array();
1120
        } else if (!$do_clone && isset(Smarty_Internal_Template::$tplObjCache[ $_templateId ])) {
1121
            $tpl = clone Smarty_Internal_Template::$tplObjCache[ $_templateId ];
1122
            $tpl->inheritance = null;
1123
            $tpl->tpl_vars = $tpl->config_vars = array();
1124
        } else {
1125
            /* @var Smarty_Internal_Template $tpl */
1126
            $tpl = new $this->template_class($template, $this, null, $cache_id, $compile_id, null, null);
1127
            $tpl->templateId = $_templateId;
1128
        }
1129
        if ($do_clone) {
1130
            $tpl->smarty = clone $tpl->smarty;
1131
        }
1132
        $tpl->parent = $parent ? $parent : $this;
1133
        // fill data if present
1134
        if (!empty($data) && is_array($data)) {
1135
            // set up variable values
1136
            foreach ($data as $_key => $_val) {
1137
                $tpl->tpl_vars[ $_key ] = new Smarty_Variable($_val);
1138
            }
1139
        }
1140
        if ($this->debugging || $this->debugging_ctrl == 'URL') {
1141
            $tpl->smarty->_debug = new Smarty_Internal_Debug();
1142
            // check URL debugging control
1143
            if (!$this->debugging && $this->debugging_ctrl == 'URL') {
1144
                $tpl->smarty->_debug->debugUrl($tpl->smarty);
1145
            }
1146
        }
1147
        return $tpl;
1148
    }
1149
1150
    /**
1151
     * Takes unknown classes and loads plugin files for them
1152
     * class name format: Smarty_PluginType_PluginName
1153
     * plugin filename format: plugintype.pluginname.php
1154
     *
1155
     * @param  string $plugin_name class plugin name to load
1156
     * @param  bool   $check       check if already loaded
1157
     *
1158
     * @throws SmartyException
1159
     * @return string |boolean filepath of loaded file or false
1160
     */
1161
    public function loadPlugin($plugin_name, $check = true)
1162
    {
1163
        return $this->ext->loadPlugin->loadPlugin($this, $plugin_name, $check);
1164
    }
1165
1166
    /**
1167
     * Get unique template id
1168
     *
1169
     * @param string                    $template_name
1170
     * @param null|mixed                $cache_id
1171
     * @param null|mixed                $compile_id
1172
     * @param null                      $caching
1173
     * @param \Smarty_Internal_Template $template
1174
     *
1175
     * @return string
1176
     */
1177
    public function _getTemplateId($template_name, $cache_id = null, $compile_id = null, $caching = null,
1178
                                   Smarty_Internal_Template $template = null)
1179
    {
1180
        $template_name = (strpos($template_name, ':') === false) ? "{$this->default_resource_type}:{$template_name}" :
1181
            $template_name;
1182
        $cache_id = $cache_id === null ? $this->cache_id : $cache_id;
1183
        $compile_id = $compile_id === null ? $this->compile_id : $compile_id;
1184
        $caching = (int) ($caching === null ? $this->caching : $caching);
1185
1186
        if ((isset($template) && strpos($template_name, ':.') !== false) || $this->allow_ambiguous_resources) {
1187
            $_templateId =
1188
                Smarty_Resource::getUniqueTemplateName((isset($template) ? $template : $this), $template_name) .
1189
                "#{$cache_id}#{$compile_id}#{$caching}";
1190
        } else {
1191
            $_templateId = $this->_joined_template_dir . "#{$template_name}#{$cache_id}#{$compile_id}#{$caching}";
1192
        }
1193
        if (isset($_templateId[ 150 ])) {
1194
            $_templateId = sha1($_templateId);
1195
        }
1196
        return $_templateId;
1197
    }
1198
1199
    /**
1200
     * Normalize path
1201
     *  - remove /./ and /../
1202
     *  - make it absolute if required
1203
     *
1204
     * @param string $path      file path
1205
     * @param bool   $realpath  if true - convert to absolute
1206
     *                          false - convert to relative
1207
     *                          null - keep as it is but remove /./ /../
1208
     *
1209
     * @return string
1210
     */
1211
    public function _realpath($path, $realpath = null)
1212
    {
1213
        $nds = $this->ds == '/' ? '\\' : '/';
1214
        // normalize $this->ds
1215
        $path = str_replace($nds, $this->ds, $path);
1216
        preg_match('%^(?<root>(?:[[:alpha:]]:[\\\\]|/|[\\\\]{2}[[:alpha:]]+|[[:print:]]{2,}:[/]{2}|[\\\\])?)(?<path>(?:[[:print:]]*))$%',
1217
                   $path, $parts);
1218
        $path = $parts[ 'path' ];
1219
        if ($parts[ 'root' ] == '\\') {
1220
            $parts[ 'root' ] = substr(getcwd(), 0, 2) . $parts[ 'root' ];
1221
        } else {
1222
            if ($realpath !== null && !$parts[ 'root' ]) {
1223
                $path = getcwd() . $this->ds . $path;
1224
            }
1225
        }
1226
        // remove noop 'DIRECTORY_SEPARATOR DIRECTORY_SEPARATOR' and 'DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR' patterns
1227
        $path = preg_replace('#([\\\\/]([.]?[\\\\/])+)#', $this->ds, $path);
1228
        // resolve '..DIRECTORY_SEPARATOR' pattern, smallest first
1229
        if (strpos($path, '..' . $this->ds) != false &&
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing strpos($path, '..' . $this->ds) of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
1230
            preg_match_all('#(([.]?[\\\\/])*([.][.])[\\\\/]([.]?[\\\\/])*)+#', $path, $match)
1231
        ) {
1232
            $counts = array();
1233
            foreach ($match[ 0 ] as $m) {
1234
                $counts[] = (int) ((strlen($m) - 1) / 3);
1235
            }
1236
            sort($counts);
1237
            foreach ($counts as $count) {
1238
                $path = preg_replace('#(([\\\\/]([.]?[\\\\/])*[^\\\\/.]+){' . $count .
1239
                                     '}[\\\\/]([.]?[\\\\/])*([.][.][\\\\/]([.]?[\\\\/])*){' . $count . '})(?=[^.])#',
1240
                                     $this->ds, $path);
1241
            }
1242
        }
1243
1244
        return $parts[ 'root' ] . $path;
1245
    }
1246
1247
    /**
1248
     * Empty template objects cache
1249
     */
1250
    public function _clearTemplateCache()
1251
    {
1252
        Smarty_Internal_Template::$isCacheTplObj = array();
1253
        Smarty_Internal_Template::$tplObjCache = array();
1254
    }
1255
1256
    /**
1257
     * Get Smarty object
1258
     *
1259
     * @return Smarty
1260
     */
1261
    public function _getSmartyObj()
1262
    {
1263
        return $this;
1264
    }
1265
1266
    /**
1267
     * @param boolean $compile_check
1268
     */
1269
    public function setCompileCheck($compile_check)
1270
    {
1271
        $this->compile_check = $compile_check;
1272
    }
1273
1274
    /**
1275
     * @param boolean $use_sub_dirs
1276
     */
1277
    public function setUseSubDirs($use_sub_dirs)
1278
    {
1279
        $this->use_sub_dirs = $use_sub_dirs;
1280
    }
1281
1282
    /**
1283
     * @param int $error_reporting
1284
     */
1285
    public function setErrorReporting($error_reporting)
1286
    {
1287
        $this->error_reporting = $error_reporting;
1288
    }
1289
1290
    /**
1291
     * @param boolean $escape_html
1292
     */
1293
    public function setEscapeHtml($escape_html)
1294
    {
1295
        $this->escape_html = $escape_html;
1296
    }
1297
1298
    /**
1299
     * @param boolean $auto_literal
1300
     */
1301
    public function setAutoLiteral($auto_literal)
1302
    {
1303
        $this->auto_literal = $auto_literal;
1304
    }
1305
1306
    /**
1307
     * @param boolean $force_compile
1308
     */
1309
    public function setForceCompile($force_compile)
1310
    {
1311
        $this->force_compile = $force_compile;
1312
    }
1313
1314
    /**
1315
     * @param boolean $merge_compiled_includes
1316
     */
1317
    public function setMergeCompiledIncludes($merge_compiled_includes)
1318
    {
1319
        $this->merge_compiled_includes = $merge_compiled_includes;
1320
    }
1321
1322
    /**
1323
     * @param string $left_delimiter
1324
     */
1325
    public function setLeftDelimiter($left_delimiter)
1326
    {
1327
        $this->left_delimiter = $left_delimiter;
1328
    }
1329
1330
    /**
1331
     * @param string $right_delimiter
1332
     */
1333
    public function setRightDelimiter($right_delimiter)
1334
    {
1335
        $this->right_delimiter = $right_delimiter;
1336
    }
1337
1338
    /**
1339
     * @param boolean $debugging
1340
     */
1341
    public function setDebugging($debugging)
1342
    {
1343
        $this->debugging = $debugging;
1344
    }
1345
1346
    /**
1347
     * @param boolean $config_overwrite
1348
     */
1349
    public function setConfigOverwrite($config_overwrite)
1350
    {
1351
        $this->config_overwrite = $config_overwrite;
1352
    }
1353
1354
    /**
1355
     * @param boolean $config_booleanize
1356
     */
1357
    public function setConfigBooleanize($config_booleanize)
1358
    {
1359
        $this->config_booleanize = $config_booleanize;
1360
    }
1361
1362
    /**
1363
     * @param boolean $config_read_hidden
1364
     */
1365
    public function setConfigReadHidden($config_read_hidden)
1366
    {
1367
        $this->config_read_hidden = $config_read_hidden;
1368
    }
1369
1370
    /**
1371
     * @param boolean $compile_locking
1372
     */
1373
    public function setCompileLocking($compile_locking)
1374
    {
1375
        $this->compile_locking = $compile_locking;
1376
    }
1377
1378
    /**
1379
     * @param string $default_resource_type
1380
     */
1381
    public function setDefaultResourceType($default_resource_type)
1382
    {
1383
        $this->default_resource_type = $default_resource_type;
1384
    }
1385
1386
    /**
1387
     * @param string $caching_type
1388
     */
1389
    public function setCachingType($caching_type)
1390
    {
1391
        $this->caching_type = $caching_type;
1392
    }
1393
1394
    /**
1395
     * Test install
1396
     *
1397
     * @param null $errors
1398
     */
1399
    public function testInstall(&$errors = null)
1400
    {
1401
        Smarty_Internal_TestInstall::testInstall($this, $errors);
1402
    }
1403
1404
    /**
1405
     * <<magic>> Generic getter.
1406
     * Calls the appropriate getter function.
1407
     * Issues an E_USER_NOTICE if no valid getter is found.
1408
     *
1409
     * @param  string $name property name
1410
     *
1411
     * @return mixed
1412
     */
1413
    public function __get($name)
1414
    {
1415
        if (isset($this->accessMap[ $name ])) {
1416
            $method = 'get' . $this->accessMap[ $name ];
1417
            return $this->{$method}();
1418
        } elseif (isset($this->_cache[ $name ])) {
1419
            return $this->_cache[ $name ];
1420
        } elseif (in_array($name, $this->obsoleteProperties)) {
1421
            return null;
1422
        } else {
1423
            trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
1424
        }
1425
        return null;
1426
    }
1427
1428
    /**
1429
     * <<magic>> Generic setter.
1430
     * Calls the appropriate setter function.
1431
     * Issues an E_USER_NOTICE if no valid setter is found.
1432
     *
1433
     * @param string $name  property name
1434
     * @param mixed  $value parameter passed to setter
1435
     */
1436
    public function __set($name, $value)
1437
    {
1438
        if (isset($this->accessMap[ $name ])) {
1439
            $method = 'set' . $this->accessMap[ $name ];
1440
            $this->{$method}($value);
1441
        } elseif (in_array($name, $this->obsoleteProperties)) {
1442
            return;
1443
        } else {
1444
            if (is_object($value) && method_exists($value, $name)) {
1445
                $this->$name = $value;
1446
            } else {
1447
                trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
1448
            }
1449
        }
1450
    }
1451
1452
    /**
1453
     * Error Handler to mute expected messages
1454
     *
1455
     * @link http://php.net/set_error_handler
1456
     *
1457
     * @param  integer $errno Error level
1458
     * @param          $errstr
1459
     * @param          $errfile
1460
     * @param          $errline
1461
     * @param          $errcontext
1462
     *
1463
     * @return bool|void
1464
     */
1465
    public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext)
1466
    {
1467
        $_is_muted_directory = false;
1468
1469
        // add the SMARTY_DIR to the list of muted directories
1470
        if (!isset(Smarty::$_muted_directories[ SMARTY_DIR ])) {
1471
            $smarty_dir = realpath(SMARTY_DIR);
1472
            if ($smarty_dir !== false) {
1473
                Smarty::$_muted_directories[ SMARTY_DIR ] =
1474
                    array('file' => $smarty_dir, 'length' => strlen($smarty_dir),);
1475
            }
1476
        }
1477
1478
        // walk the muted directories and test against $errfile
1479
        foreach (Smarty::$_muted_directories as $key => &$dir) {
1480
            if (!$dir) {
1481
                // resolve directory and length for speedy comparisons
1482
                $file = realpath($key);
1483
                if ($file === false) {
1484
                    // this directory does not exist, remove and skip it
1485
                    unset(Smarty::$_muted_directories[ $key ]);
1486
                    continue;
1487
                }
1488
                $dir = array('file' => $file, 'length' => strlen($file),);
1489
            }
1490
            if (!strncmp($errfile, $dir[ 'file' ], $dir[ 'length' ])) {
1491
                $_is_muted_directory = true;
1492
                break;
1493
            }
1494
        }
1495
        // pass to next error handler if this error did not occur inside SMARTY_DIR
1496
        // or the error was within smarty but masked to be ignored
1497
        if (!$_is_muted_directory || ($errno && $errno & error_reporting())) {
1498
            if (Smarty::$_previous_error_handler) {
1499
                return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline,
1500
                                      $errcontext);
1501
            } else {
1502
                return false;
1503
            }
1504
        }
1505
        return;
1506
    }
1507
1508
    /**
1509
     * Enable error handler to mute expected messages
1510
     *
1511
     * @return void
1512
     */
1513
    public static function muteExpectedErrors()
1514
    {
1515
        /*
1516
            error muting is done because some people implemented custom error_handlers using
1517
            http://php.net/set_error_handler and for some reason did not understand the following paragraph:
1518
1519
                It is important to remember that the standard PHP error handler is completely bypassed for the
1520
                error types specified by error_types unless the callback function returns FALSE.
1521
                error_reporting() settings will have no effect and your error handler will be called regardless -
1522
                however you are still able to read the current value of error_reporting and act appropriately.
1523
                Of particular note is that this value will be 0 if the statement that caused the error was
1524
                prepended by the @ error-control operator.
1525
1526
            Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include
1527
                - @filemtime() is almost twice as fast as using an additional file_exists()
1528
                - between file_exists() and filemtime() a possible race condition is opened,
1529
                  which does not exist using the simple @filemtime() approach.
1530
        */
1531
        $error_handler = array('Smarty', 'mutingErrorHandler');
1532
        $previous = set_error_handler($error_handler);
1533
1534
        // avoid dead loops
1535
        if ($previous !== $error_handler) {
1536
            Smarty::$_previous_error_handler = $previous;
1537
        }
1538
    }
1539
1540
    /**
1541
     * Disable error handler muting expected messages
1542
     *
1543
     * @return void
1544
     */
1545
    public static function unmuteExpectedErrors()
1546
    {
1547
        restore_error_handler();
1548
    }
1549
}
1550