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