source: pro-violet-viettel/sourcecode/application/third_party/Smarty/Smarty.class.php @ 345

Last change on this file since 345 was 345, checked in by quyenla, 11 years ago

collaborator page

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