Subversion Repositories ALCASAR

Rev

Details | Last modification | View Log

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