搜尋
首頁後端開發php教程php封裝的smarty類別完整實例_php實例

本文实例讲述了php封装的smarty类。分享给大家供大家参考,具体如下:

<&#63;php
/**
 * Project:   Smarty: the PHP compiling template engine
 * File:    Smarty.class.php
 * SVN:     $Id: Smarty.class.php 4848 2014-06-08 18:12:09Z Uwe.Tews@googlemail.com $
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 * For questions, help, comments, discussion, etc., please join the
 * Smarty mailing list. Send a blank e-mail to
 * smarty-discussion-subscribe@googlegroups.com
 *
 * @link   http://www.smarty.net/
 * @copyright 2008 New Digital Group, Inc.
 * @author  Monte Ohrt <monte at ohrt dot com>
 * @author  Uwe Tews
 * @author  Rodney Rehm
 * @package  Smarty
 * @version  3.1.19
 */
/**
 * define shorthand directory separator constant
 */
if (!defined('DS')) {
  define('DS', DIRECTORY_SEPARATOR);
}
/**
 * set SMARTY_DIR to absolute path to Smarty library files.
 * Sets SMARTY_DIR only if user application has not already defined it.
 */
if (!defined('SMARTY_DIR')) {
  define('SMARTY_DIR', dirname(__FILE__) . DS);
}
/**
 * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins.
 * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it.
 */
if (!defined('SMARTY_SYSPLUGINS_DIR')) {
  define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DS);
}
if (!defined('SMARTY_PLUGINS_DIR')) {
  define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS);
}
if (!defined('SMARTY_MBSTRING')) {
  define('SMARTY_MBSTRING', function_exists('mb_split'));
}
if (!defined('SMARTY_RESOURCE_CHAR_SET')) {
  // UTF-8 can only be done properly when mbstring is available!
  /**
   * @deprecated in favor of Smarty::$_CHARSET
   */
  define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING &#63; 'UTF-8' : 'ISO-8859-1');
}
if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) {
  /**
   * @deprecated in favor of Smarty::$_DATE_FORMAT
   */
  define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y');
}
/**
 * register the class autoloader
 */
if (!defined('SMARTY_SPL_AUTOLOAD')) {
  define('SMARTY_SPL_AUTOLOAD', 0);
}
if (SMARTY_SPL_AUTOLOAD && set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false) {
  $registeredAutoLoadFunctions = spl_autoload_functions();
  if (!isset($registeredAutoLoadFunctions['spl_autoload'])) {
    spl_autoload_register();
  }
} else {
  spl_autoload_register('smartyAutoload');
}
/**
 * Load always needed external class files
 */
include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php';
include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php';
include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php';
include_once SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php';
include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_resource_file.php';
include_once SMARTY_SYSPLUGINS_DIR . 'smarty_cacheresource.php';
include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_cacheresource_file.php';
/**
 * This is the main Smarty class
 *
 * @package Smarty
 */
class Smarty extends Smarty_Internal_TemplateBase
{
  /**#@+
   * constant definitions
   */
  /**
   * smarty version
   */
  const SMARTY_VERSION = 'Smarty-3.1.19';
  /**
   * define variable scopes
   */
  const SCOPE_LOCAL = 0;
  const SCOPE_PARENT = 1;
  const SCOPE_ROOT = 2;
  const SCOPE_GLOBAL = 3;
  /**
   * define caching modes
   */
  const CACHING_OFF = 0;
  const CACHING_LIFETIME_CURRENT = 1;
  const CACHING_LIFETIME_SAVED = 2;
  /**
   * define constant for clearing cache files be saved expiration datees
   */
  const CLEAR_EXPIRED = - 1;
  /**
   * define compile check modes
   */
  const COMPILECHECK_OFF = 0;
  const COMPILECHECK_ON = 1;
  const COMPILECHECK_CACHEMISS = 2;
  /**
   * modes for handling of "<&#63;php ... &#63;>" tags in templates.
   */
  const PHP_PASSTHRU = 0; //-> print tags as plain text
  const PHP_QUOTE = 1; //-> escape tags as entities
  const PHP_REMOVE = 2; //-> escape tags as entities
  const PHP_ALLOW = 3; //-> escape tags as entities
  /**
   * filter types
   */
  const FILTER_POST = 'post';
  const FILTER_PRE = 'pre';
  const FILTER_OUTPUT = 'output';
  const FILTER_VARIABLE = 'variable';
  /**
   * plugin types
   */
  const PLUGIN_FUNCTION = 'function';
  const PLUGIN_BLOCK = 'block';
  const PLUGIN_COMPILER = 'compiler';
  const PLUGIN_MODIFIER = 'modifier';
  const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler';
  /**#@-*/
  /**
   * assigned global tpl vars
   */
  public static $global_tpl_vars = array();
  /**
   * error handler returned by set_error_hanlder() in Smarty::muteExpectedErrors()
   */
  public static $_previous_error_handler = null;
  /**
   * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors()
   */
  public static $_muted_directories = array();
  /**
   * Flag denoting if Multibyte String functions are available
   */
  public static $_MBSTRING = SMARTY_MBSTRING;
  /**
   * The character set to adhere to (e.g. "UTF-8")
   */
  public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET;
  /**
   * The date format to be used internally
   * (accepts date() and strftime())
   */
  public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT;
  /**
   * Flag denoting if PCRE should run in UTF-8 mode
   */
  public static $_UTF8_MODIFIER = 'u';
  /**
   * Flag denoting if operating system is windows
   */
  public static $_IS_WINDOWS = false;
  /**#@+
   * variables
   */
  /**
   * auto literal on delimiters with whitspace
   *
   * @var boolean
   */
  public $auto_literal = true;
  /**
   * display error on not assigned variables
   *
   * @var boolean
   */
  public $error_unassigned = false;
  /**
   * look up relative filepaths in include_path
   *
   * @var boolean
   */
  public $use_include_path = false;
  /**
   * template directory
   *
   * @var array
   */
  private $template_dir = array();
  /**
   * joined template directory string used in cache keys
   *
   * @var string
   */
  public $joined_template_dir = null;
  /**
   * joined config directory string used in cache keys
   *
   * @var string
   */
  public $joined_config_dir = null;
  /**
   * default template handler
   *
   * @var callable
   */
  public $default_template_handler_func = null;
  /**
   * default config handler
   *
   * @var callable
   */
  public $default_config_handler_func = null;
  /**
   * default plugin handler
   *
   * @var callable
   */
  public $default_plugin_handler_func = null;
  /**
   * compile directory
   *
   * @var string
   */
  private $compile_dir = null;
  /**
   * plugins directory
   *
   * @var array
   */
  private $plugins_dir = array();
  /**
   * cache directory
   *
   * @var string
   */
  private $cache_dir = null;
  /**
   * config directory
   *
   * @var array
   */
  private $config_dir = array();
  /**
   * force template compiling&#63;
   *
   * @var boolean
   */
  public $force_compile = false;
  /**
   * check template for modifications&#63;
   *
   * @var boolean
   */
  public $compile_check = true;
  /**
   * use sub dirs for compiled/cached files&#63;
   *
   * @var boolean
   */
  public $use_sub_dirs = false;
  /**
   * allow ambiguous resources (that are made unique by the resource handler)
   *
   * @var boolean
   */
  public $allow_ambiguous_resources = false;
  /**
   * caching enabled
   *
   * @var boolean
   */
  public $caching = false;
  /**
   * merge compiled includes
   *
   * @var boolean
   */
  public $merge_compiled_includes = false;
  /**
   * template inheritance merge compiled includes
   *
   * @var boolean
   */
  public $inheritance_merge_compiled_includes = true;
  /**
   * cache lifetime in seconds
   *
   * @var integer
   */
  public $cache_lifetime = 3600;
  /**
   * force cache file creation
   *
   * @var boolean
   */
  public $force_cache = false;
  /**
   * Set this if you want different sets of cache files for the same
   * templates.
   *
   * @var string
   */
  public $cache_id = null;
  /**
   * Set this if you want different sets of compiled files for the same
   * templates.
   *
   * @var string
   */
  public $compile_id = null;
  /**
   * template left-delimiter
   *
   * @var string
   */
  public $left_delimiter = "{";
  /**
   * template right-delimiter
   *
   * @var string
   */
  public $right_delimiter = "}";
  /**#@+
   * security
   */
  /**
   * class name
   * This should be instance of Smarty_Security.
   *
   * @var string
   * @see Smarty_Security
   */
  public $security_class = 'Smarty_Security';
  /**
   * implementation of security class
   *
   * @var Smarty_Security
   */
  public $security_policy = null;
  /**
   * controls handling of PHP-blocks
   *
   * @var integer
   */
  public $php_handling = self::PHP_PASSTHRU;
  /**
   * controls if the php template file resource is allowed
   *
   * @var bool
   */
  public $allow_php_templates = false;
  /**
   * Should compiled-templates be prevented from being called directly&#63;
   * {@internal
   * Currently used by Smarty_Internal_Template only.
   * }}
   *
   * @var boolean
   */
  public $direct_access_security = true;
  /**#@-*/
  /**
   * debug mode
   * Setting this to true enables the debug-console.
   *
   * @var boolean
   */
  public $debugging = false;
  /**
   * This determines if debugging is enable-able from the browser.
   * <ul>
   * <li>NONE => no debugging control allowed</li>
   * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
   * </ul>
   *
   * @var string
   */
  public $debugging_ctrl = 'NONE';
  /**
   * Name of debugging URL-param.
   * Only used when $debugging_ctrl is set to 'URL'.
   * The name of the URL-parameter that activates debugging.
   *
   * @var type
   */
  public $smarty_debug_id = 'SMARTY_DEBUG';
  /**
   * Path of debug template.
   *
   * @var string
   */
  public $debug_tpl = null;
  /**
   * When set, smarty uses this value as error_reporting-level.
   *
   * @var int
   */
  public $error_reporting = null;
  /**
   * Internal flag for getTags()
   *
   * @var boolean
   */
  public $get_used_tags = false;
  /**#@+
   * config var settings
   */
  /**
   * Controls whether variables with the same name overwrite each other.
   *
   * @var boolean
   */
  public $config_overwrite = true;
  /**
   * Controls whether config values of on/true/yes and off/false/no get converted to boolean.
   *
   * @var boolean
   */
  public $config_booleanize = true;
  /**
   * Controls whether hidden config sections/vars are read from the file.
   *
   * @var boolean
   */
  public $config_read_hidden = false;
  /**#@-*/
  /**#@+
   * resource locking
   */
  /**
   * locking concurrent compiles
   *
   * @var boolean
   */
  public $compile_locking = true;
  /**
   * Controls whether cache resources should emply locking mechanism
   *
   * @var boolean
   */
  public $cache_locking = false;
  /**
   * seconds to wait for acquiring a lock before ignoring the write lock
   *
   * @var float
   */
  public $locking_timeout = 10;
  /**#@-*/
  /**
   * global template functions
   *
   * @var array
   */
  public $template_functions = array();
  /**
   * resource type used if none given
   * Must be an valid key of $registered_resources.
   *
   * @var string
   */
  public $default_resource_type = 'file';
  /**
   * caching type
   * Must be an element of $cache_resource_types.
   *
   * @var string
   */
  public $caching_type = 'file';
  /**
   * internal config properties
   *
   * @var array
   */
  public $properties = array();
  /**
   * config type
   *
   * @var string
   */
  public $default_config_type = 'file';
  /**
   * cached template objects
   *
   * @var array
   */
  public $template_objects = array();
  /**
   * check If-Modified-Since headers
   *
   * @var boolean
   */
  public $cache_modified_check = false;
  /**
   * registered plugins
   *
   * @var array
   */
  public $registered_plugins = array();
  /**
   * plugin search order
   *
   * @var array
   */
  public $plugin_search_order = array('function', 'block', 'compiler', 'class');
  /**
   * registered objects
   *
   * @var array
   */
  public $registered_objects = array();
  /**
   * registered classes
   *
   * @var array
   */
  public $registered_classes = array();
  /**
   * registered filters
   *
   * @var array
   */
  public $registered_filters = array();
  /**
   * registered resources
   *
   * @var array
   */
  public $registered_resources = array();
  /**
   * resource handler cache
   *
   * @var array
   */
  public $_resource_handlers = array();
  /**
   * registered cache resources
   *
   * @var array
   */
  public $registered_cache_resources = array();
  /**
   * cache resource handler cache
   *
   * @var array
   */
  public $_cacheresource_handlers = array();
  /**
   * autoload filter
   *
   * @var array
   */
  public $autoload_filters = array();
  /**
   * default modifier
   *
   * @var array
   */
  public $default_modifiers = array();
  /**
   * autoescape variable output
   *
   * @var boolean
   */
  public $escape_html = false;
  /**
   * global internal smarty vars
   *
   * @var array
   */
  public static $_smarty_vars = array();
  /**
   * start time for execution time calculation
   *
   * @var int
   */
  public $start_time = 0;
  /**
   * default file permissions
   *
   * @var int
   */
  public $_file_perms = 0644;
  /**
   * default dir permissions
   *
   * @var int
   */
  public $_dir_perms = 0771;
  /**
   * block tag hierarchy
   *
   * @var array
   */
  public $_tag_stack = array();
  /**
   * self pointer to Smarty object
   *
   * @var Smarty
   */
  public $smarty;
  /**
   * required by the compiler for BC
   *
   * @var string
   */
  public $_current_file = null;
  /**
   * internal flag to enable parser debugging
   *
   * @var bool
   */
  public $_parserdebug = false;
  /**
   * Saved parameter of merged templates during compilation
   *
   * @var array
   */
  public $merged_templates_func = array();
  /**#@-*/
  /**
   * Initialize new Smarty object
   */
  public function __construct()
  {
    // selfpointer needed by some other class methods
    $this->smarty = $this;
    if (is_callable('mb_internal_encoding')) {
      mb_internal_encoding(Smarty::$_CHARSET);
    }
    $this->start_time = microtime(true);
    // set default dirs
    $this->setTemplateDir('.' . DS . 'templates' . DS)
      ->setCompileDir('.' . DS . 'templates_c' . DS)
      ->setPluginsDir(SMARTY_PLUGINS_DIR)
      ->setCacheDir('.' . DS . 'cache' . DS)
      ->setConfigDir('.' . DS . 'configs' . DS);
    $this->debug_tpl = 'file:' . dirname(__FILE__) . '/debug.tpl';
    if (isset($_SERVER['SCRIPT_NAME'])) {
      $this->assignGlobal('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']);
    }
  }
  /**
   * Class destructor
   */
  public function __destruct()
  {
    // intentionally left blank
  }
  /**
   * <<magic>> set selfpointer on cloned object
   */
  public function __clone()
  {
    $this->smarty = $this;
  }
  /**
   * <<magic>> Generic getter.
   * Calls the appropriate getter function.
   * Issues an E_USER_NOTICE if no valid getter is found.
   *
   * @param string $name property name
   *
   * @return mixed
   */
  public function __get($name)
  {
    $allowed = array(
      'template_dir' => 'getTemplateDir',
      'config_dir'  => 'getConfigDir',
      'plugins_dir' => 'getPluginsDir',
      'compile_dir' => 'getCompileDir',
      'cache_dir'  => 'getCacheDir',
    );
    if (isset($allowed[$name])) {
      return $this->{$allowed[$name]}();
    } else {
      trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
    }
  }
  /**
   * <<magic>> Generic setter.
   * Calls the appropriate setter function.
   * Issues an E_USER_NOTICE if no valid setter is found.
   *
   * @param string $name property name
   * @param mixed $value parameter passed to setter
   */
  public function __set($name, $value)
  {
    $allowed = array(
      'template_dir' => 'setTemplateDir',
      'config_dir'  => 'setConfigDir',
      'plugins_dir' => 'setPluginsDir',
      'compile_dir' => 'setCompileDir',
      'cache_dir'  => 'setCacheDir',
    );
    if (isset($allowed[$name])) {
      $this->{$allowed[$name]}($value);
    } else {
      trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
    }
  }
  /**
   * Check if a template resource exists
   *
   * @param string $resource_name template name
   *
   * @return boolean status
   */
  public function templateExists($resource_name)
  {
    // create template object
    $save = $this->template_objects;
    $tpl = new $this->template_class($resource_name, $this);
    // check if it does exists
    $result = $tpl->source->exists;
    $this->template_objects = $save;
    return $result;
  }
  /**
   * Returns a single or all global variables
   *
   * @param string $varname variable name or null
   *
   * @return string variable value or or array of variables
   */
  public function getGlobal($varname = null)
  {
    if (isset($varname)) {
      if (isset(self::$global_tpl_vars[$varname])) {
        return self::$global_tpl_vars[$varname]->value;
      } else {
        return '';
      }
    } else {
      $_result = array();
      foreach (self::$global_tpl_vars AS $key => $var) {
        $_result[$key] = $var->value;
      }
      return $_result;
    }
  }
  /**
   * Empty cache folder
   *
   * @param integer $exp_time expiration time
   * @param string $type   resource type
   *
   * @return integer number of cache files deleted
   */
  public function clearAllCache($exp_time = null, $type = null)
  {
    // load cache resource and call clearAll
    $_cache_resource = Smarty_CacheResource::load($this, $type);
    Smarty_CacheResource::invalidLoadedCache($this);
    return $_cache_resource->clearAll($this, $exp_time);
  }
  /**
   * Empty cache for a specific template
   *
   * @param string $template_name template name
   * @param string $cache_id   cache id
   * @param string $compile_id  compile id
   * @param integer $exp_time   expiration time
   * @param string $type     resource type
   *
   * @return integer number of cache files deleted
   */
  public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
  {
    // load cache resource and call clear
    $_cache_resource = Smarty_CacheResource::load($this, $type);
    Smarty_CacheResource::invalidLoadedCache($this);
    return $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time);
  }
  /**
   * Loads security class and enables security
   *
   * @param string|Smarty_Security $security_class if a string is used, it must be class-name
   *
   * @return Smarty         current Smarty instance for chaining
   * @throws SmartyException    when an invalid class name is provided
   */
  public function enableSecurity($security_class = null)
  {
    if ($security_class instanceof Smarty_Security) {
      $this->security_policy = $security_class;
      return $this;
    } elseif (is_object($security_class)) {
      throw new SmartyException("Class '" . get_class($security_class) . "' must extend Smarty_Security.");
    }
    if ($security_class == null) {
      $security_class = $this->security_class;
    }
    if (!class_exists($security_class)) {
      throw new SmartyException("Security class '$security_class' is not defined");
    } elseif ($security_class !== 'Smarty_Security' && !is_subclass_of($security_class, 'Smarty_Security')) {
      throw new SmartyException("Class '$security_class' must extend Smarty_Security.");
    } else {
      $this->security_policy = new $security_class($this);
    }
    return $this;
  }
  /**
   * Disable security
   *
   * @return Smarty current Smarty instance for chaining
   */
  public function disableSecurity()
  {
    $this->security_policy = null;
    return $this;
  }
  /**
   * Set template directory
   *
   * @param string|array $template_dir directory(s) of template sources
   *
   * @return Smarty    current Smarty instance for chaining
   */
  public function setTemplateDir($template_dir)
  {
    $this->template_dir = array();
    foreach ((array) $template_dir as $k => $v) {
      $this->template_dir[$k] = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS;
    }
    $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir);
    return $this;
  }
  /**
   * Add template directory(s)
   *
   * @param string|array $template_dir directory(s) of template sources
   * @param string    $key     of the array element to assign the template dir to
   *
   * @return Smarty     current Smarty instance for chaining
   * @throws SmartyException when the given template directory is not valid
   */
  public function addTemplateDir($template_dir, $key = null)
  {
    // make sure we're dealing with an array
    $this->template_dir = (array) $this->template_dir;
    if (is_array($template_dir)) {
      foreach ($template_dir as $k => $v) {
        $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS;
        if (is_int($k)) {
          // indexes are not merged but appended
          $this->template_dir[] = $v;
        } else {
          // string indexes are overridden
          $this->template_dir[$k] = $v;
        }
      }
    } else {
      $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($template_dir, '/\\')) . DS;
      if ($key !== null) {
        // override directory at specified index
        $this->template_dir[$key] = $v;
      } else {
        // append new directory
        $this->template_dir[] = $v;
      }
    }
    $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir);
    return $this;
  }
  /**
   * Get template directories
   *
   * @param mixed $index index of directory to get, null to get all
   *
   * @return array|string list of template directories, or directory of $index
   */
  public function getTemplateDir($index = null)
  {
    if ($index !== null) {
      return isset($this->template_dir[$index]) &#63; $this->template_dir[$index] : null;
    }
    return (array) $this->template_dir;
  }
  /**
   * Set config directory
   *
   * @param $config_dir
   *
   * @return Smarty    current Smarty instance for chaining
   */
  public function setConfigDir($config_dir)
  {
    $this->config_dir = array();
    foreach ((array) $config_dir as $k => $v) {
      $this->config_dir[$k] = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS;
    }
    $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir);
    return $this;
  }
  /**
   * Add config directory(s)
   *
   * @param string|array    $config_dir directory(s) of config sources
   * @param mixed $key    key of the array element to assign the config dir to
   *
   * @return Smarty current Smarty instance for chaining
   */
  public function addConfigDir($config_dir, $key = null)
  {
    // make sure we're dealing with an array
    $this->config_dir = (array) $this->config_dir;
    if (is_array($config_dir)) {
      foreach ($config_dir as $k => $v) {
        $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS;
        if (is_int($k)) {
          // indexes are not merged but appended
          $this->config_dir[] = $v;
        } else {
          // string indexes are overridden
          $this->config_dir[$k] = $v;
        }
      }
    } else {
      $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($config_dir, '/\\')) . DS;
      if ($key !== null) {
        // override directory at specified index
        $this->config_dir[$key] = rtrim($v, '/\\') . DS;
      } else {
        // append new directory
        $this->config_dir[] = rtrim($v, '/\\') . DS;
      }
    }
    $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir);
    return $this;
  }
  /**
   * Get config directory
   *
   * @param mixed $index index of directory to get, null to get all
   *
   * @return array|string configuration directory
   */
  public function getConfigDir($index = null)
  {
    if ($index !== null) {
      return isset($this->config_dir[$index]) &#63; $this->config_dir[$index] : null;
    }
    return (array) $this->config_dir;
  }
  /**
   * Set plugins directory
   *
   * @param string|array $plugins_dir directory(s) of plugins
   *
   * @return Smarty    current Smarty instance for chaining
   */
  public function setPluginsDir($plugins_dir)
  {
    $this->plugins_dir = array();
    foreach ((array) $plugins_dir as $k => $v) {
      $this->plugins_dir[$k] = rtrim($v, '/\\') . DS;
    }
    return $this;
  }
  /**
   * Adds directory of plugin files
   *
   * @param $plugins_dir
   *
   * @return Smarty current Smarty instance for chaining
   */
  public function addPluginsDir($plugins_dir)
  {
    // make sure we're dealing with an array
    $this->plugins_dir = (array) $this->plugins_dir;
    if (is_array($plugins_dir)) {
      foreach ($plugins_dir as $k => $v) {
        if (is_int($k)) {
          // indexes are not merged but appended
          $this->plugins_dir[] = rtrim($v, '/\\') . DS;
        } else {
          // string indexes are overridden
          $this->plugins_dir[$k] = rtrim($v, '/\\') . DS;
        }
      }
    } else {
      // append new directory
      $this->plugins_dir[] = rtrim($plugins_dir, '/\\') . DS;
    }
    $this->plugins_dir = array_unique($this->plugins_dir);
    return $this;
  }
  /**
   * Get plugin directories
   *
   * @return array list of plugin directories
   */
  public function getPluginsDir()
  {
    return (array) $this->plugins_dir;
  }
  /**
   * Set compile directory
   *
   * @param string $compile_dir directory to store compiled templates in
   *
   * @return Smarty current Smarty instance for chaining
   */
  public function setCompileDir($compile_dir)
  {
    $this->compile_dir = rtrim($compile_dir, '/\\') . DS;
    if (!isset(Smarty::$_muted_directories[$this->compile_dir])) {
      Smarty::$_muted_directories[$this->compile_dir] = null;
    }
    return $this;
  }
  /**
   * Get compiled directory
   *
   * @return string path to compiled templates
   */
  public function getCompileDir()
  {
    return $this->compile_dir;
  }
  /**
   * Set cache directory
   *
   * @param string $cache_dir directory to store cached templates in
   *
   * @return Smarty current Smarty instance for chaining
   */
  public function setCacheDir($cache_dir)
  {
    $this->cache_dir = rtrim($cache_dir, '/\\') . DS;
    if (!isset(Smarty::$_muted_directories[$this->cache_dir])) {
      Smarty::$_muted_directories[$this->cache_dir] = null;
    }
    return $this;
  }
  /**
   * Get cache directory
   *
   * @return string path of cache directory
   */
  public function getCacheDir()
  {
    return $this->cache_dir;
  }
  /**
   * Set default modifiers
   *
   * @param array|string $modifiers modifier or list of modifiers to set
   *
   * @return Smarty    current Smarty instance for chaining
   */
  public function setDefaultModifiers($modifiers)
  {
    $this->default_modifiers = (array) $modifiers;
    return $this;
  }
  /**
   * Add default modifiers
   *
   * @param array|string $modifiers modifier or list of modifiers to add
   *
   * @return Smarty    current Smarty instance for chaining
   */
  public function addDefaultModifiers($modifiers)
  {
    if (is_array($modifiers)) {
      $this->default_modifiers = array_merge($this->default_modifiers, $modifiers);
    } else {
      $this->default_modifiers[] = $modifiers;
    }
    return $this;
  }
  /**
   * Get default modifiers
   *
   * @return array list of default modifiers
   */
  public function getDefaultModifiers()
  {
    return $this->default_modifiers;
  }
  /**
   * Set autoload filters
   *
   * @param array $filters filters to load automatically
   * @param string $type  "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types
   *
   * @return Smarty current Smarty instance for chaining
   */
  public function setAutoloadFilters($filters, $type = null)
  {
    if ($type !== null) {
      $this->autoload_filters[$type] = (array) $filters;
    } else {
      $this->autoload_filters = (array) $filters;
    }
    return $this;
  }
  /**
   * Add autoload filters
   *
   * @param array $filters filters to load automatically
   * @param string $type  "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types
   *
   * @return Smarty current Smarty instance for chaining
   */
  public function addAutoloadFilters($filters, $type = null)
  {
    if ($type !== null) {
      if (!empty($this->autoload_filters[$type])) {
        $this->autoload_filters[$type] = array_merge($this->autoload_filters[$type], (array) $filters);
      } else {
        $this->autoload_filters[$type] = (array) $filters;
      }
    } else {
      foreach ((array) $filters as $key => $value) {
        if (!empty($this->autoload_filters[$key])) {
          $this->autoload_filters[$key] = array_merge($this->autoload_filters[$key], (array) $value);
        } else {
          $this->autoload_filters[$key] = (array) $value;
        }
      }
    }
    return $this;
  }
  /**
   * Get autoload filters
   *
   * @param string $type type of filter to get autoloads for. Defaults to all autoload filters
   *
   * @return array array( 'type1' => array( 'filter1', 'filter2', … ) ) or array( 'filter1', 'filter2', …) if $type was specified
   */
  public function getAutoloadFilters($type = null)
  {
    if ($type !== null) {
      return isset($this->autoload_filters[$type]) &#63; $this->autoload_filters[$type] : array();
    }
    return $this->autoload_filters;
  }
  /**
   * return name of debugging template
   *
   * @return string
   */
  public function getDebugTemplate()
  {
    return $this->debug_tpl;
  }
  /**
   * set the debug template
   *
   * @param string $tpl_name
   *
   * @return Smarty     current Smarty instance for chaining
   * @throws SmartyException if file is not readable
   */
  public function setDebugTemplate($tpl_name)
  {
    if (!is_readable($tpl_name)) {
      throw new SmartyException("Unknown file '{$tpl_name}'");
    }
    $this->debug_tpl = $tpl_name;
    return $this;
  }
  /**
   * creates a template object
   *
   * @param string $template  the resource handle of the template file
   * @param mixed  $cache_id  cache id to be used with this template
   * @param mixed  $compile_id compile id to be used with this template
   * @param object $parent   next higher level of Smarty variables
   * @param boolean $do_clone  flag is Smarty object shall be cloned
   *
   * @return object template object
   */
  public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true)
  {
    if ($cache_id !== null && (is_object($cache_id) || is_array($cache_id))) {
      $parent = $cache_id;
      $cache_id = null;
    }
    if ($parent !== null && is_array($parent)) {
      $data = $parent;
      $parent = null;
    } else {
      $data = null;
    }
    // default to cache_id and compile_id of Smarty object
    $cache_id = $cache_id === null &#63; $this->cache_id : $cache_id;
    $compile_id = $compile_id === null &#63; $this->compile_id : $compile_id;
    // already in template cache&#63;
    if ($this->allow_ambiguous_resources) {
      $_templateId = Smarty_Resource::getUniqueTemplateName($this, $template) . $cache_id . $compile_id;
    } else {
      $_templateId = $this->joined_template_dir . '#' . $template . $cache_id . $compile_id;
    }
    if (isset($_templateId[150])) {
      $_templateId = sha1($_templateId);
    }
    if ($do_clone) {
      if (isset($this->template_objects[$_templateId])) {
        // return cached template object
        $tpl = clone $this->template_objects[$_templateId];
        $tpl->smarty = clone $tpl->smarty;
        $tpl->parent = $parent;
        $tpl->tpl_vars = array();
        $tpl->config_vars = array();
      } else {
        $tpl = new $this->template_class($template, clone $this, $parent, $cache_id, $compile_id);
      }
    } else {
      if (isset($this->template_objects[$_templateId])) {
        // return cached template object
        $tpl = $this->template_objects[$_templateId];
        $tpl->parent = $parent;
        $tpl->tpl_vars = array();
        $tpl->config_vars = array();
      } else {
        $tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id);
      }
    }
    // fill data if present
    if (!empty($data) && is_array($data)) {
      // set up variable values
      foreach ($data as $_key => $_val) {
        $tpl->tpl_vars[$_key] = new Smarty_variable($_val);
      }
    }
    return $tpl;
  }
  /**
   * Takes unknown classes and loads plugin files for them
   * class name format: Smarty_PluginType_PluginName
   * plugin filename format: plugintype.pluginname.php
   *
   * @param string $plugin_name class plugin name to load
   * @param bool  $check    check if already loaded
   *
   * @throws SmartyException
   * @return string |boolean filepath of loaded file or false
   */
  public function loadPlugin($plugin_name, $check = true)
  {
    // if function or class exists, exit silently (already loaded)
    if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) {
      return true;
    }
    // Plugin name is expected to be: Smarty_[Type]_[Name]
    $_name_parts = explode('_', $plugin_name, 3);
    // class name must have three parts to be valid plugin
    // count($_name_parts) < 3 === !isset($_name_parts[2])
    if (!isset($_name_parts[2]) || strtolower($_name_parts[0]) !== 'smarty') {
      throw new SmartyException("plugin {$plugin_name} is not a valid name format");
    }
    // if type is "internal", get plugin from sysplugins
    if (strtolower($_name_parts[1]) == 'internal') {
      $file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php';
      if (file_exists($file)) {
        require_once($file);
        return $file;
      } else {
        return false;
      }
    }
    // plugin filename is expected to be: [type].[name].php
    $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php";
    $_stream_resolve_include_path = function_exists('stream_resolve_include_path');
    // loop through plugin dirs and find the plugin
    foreach ($this->getPluginsDir() as $_plugin_dir) {
      $names = array(
        $_plugin_dir . $_plugin_filename,
        $_plugin_dir . strtolower($_plugin_filename),
      );
      foreach ($names as $file) {
        if (file_exists($file)) {
          require_once($file);
          return $file;
        }
        if ($this->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
          // try PHP include_path
          if ($_stream_resolve_include_path) {
            $file = stream_resolve_include_path($file);
          } else {
            $file = Smarty_Internal_Get_Include_Path::getIncludePath($file);
          }
          if ($file !== false) {
            require_once($file);
            return $file;
          }
        }
      }
    }
    // no plugin loaded
    return false;
  }
  /**
   * Compile all template files
   *
   * @param string $extension   file extension
   * @param bool  $force_compile force all to recompile
   * @param int  $time_limit
   * @param int  $max_errors
   *
   * @return integer number of template files recompiled
   */
  public function compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
  {
    return Smarty_Internal_Utility::compileAllTemplates($extension, $force_compile, $time_limit, $max_errors, $this);
  }
  /**
   * Compile all config files
   *
   * @param string $extension   file extension
   * @param bool  $force_compile force all to recompile
   * @param int  $time_limit
   * @param int  $max_errors
   *
   * @return integer number of template files recompiled
   */
  public function compileAllConfig($extension = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null)
  {
    return Smarty_Internal_Utility::compileAllConfig($extension, $force_compile, $time_limit, $max_errors, $this);
  }
  /**
   * Delete compiled template file
   *
   * @param string $resource_name template name
   * @param string $compile_id  compile id
   * @param integer $exp_time   expiration time
   *
   * @return integer number of template files deleted
   */
  public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
  {
    return Smarty_Internal_Utility::clearCompiledTemplate($resource_name, $compile_id, $exp_time, $this);
  }
  /**
   * Return array of tag/attributes of all tags used by an template
   *
   * @param Smarty_Internal_Template $template
   *
   * @return array of tag/attributes
   */
  public function getTags(Smarty_Internal_Template $template)
  {
    return Smarty_Internal_Utility::getTags($template);
  }
  /**
   * Run installation test
   *
   * @param array $errors Array to write errors into, rather than outputting them
   *
   * @return boolean true if setup is fine, false if something is wrong
   */
  public function testInstall(&$errors = null)
  {
    return Smarty_Internal_Utility::testInstall($this, $errors);
  }
  /**
   * Error Handler to mute expected messages
   *
   * @link http://php.net/set_error_handler
   *
   * @param integer $errno Error level
   * @param     $errstr
   * @param     $errfile
   * @param     $errline
   * @param     $errcontext
   *
   * @return boolean
   */
  public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext)
  {
    $_is_muted_directory = false;
    // add the SMARTY_DIR to the list of muted directories
    if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) {
      $smarty_dir = realpath(SMARTY_DIR);
      if ($smarty_dir !== false) {
        Smarty::$_muted_directories[SMARTY_DIR] = array(
          'file'  => $smarty_dir,
          'length' => strlen($smarty_dir),
        );
      }
    }
    // walk the muted directories and test against $errfile
    foreach (Smarty::$_muted_directories as $key => &$dir) {
      if (!$dir) {
        // resolve directory and length for speedy comparisons
        $file = realpath($key);
        if ($file === false) {
          // this directory does not exist, remove and skip it
          unset(Smarty::$_muted_directories[$key]);
          continue;
        }
        $dir = array(
          'file'  => $file,
          'length' => strlen($file),
        );
      }
      if (!strncmp($errfile, $dir['file'], $dir['length'])) {
        $_is_muted_directory = true;
        break;
      }
    }
    // pass to next error handler if this error did not occur inside SMARTY_DIR
    // or the error was within smarty but masked to be ignored
    if (!$_is_muted_directory || ($errno && $errno & error_reporting())) {
      if (Smarty::$_previous_error_handler) {
        return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline, $errcontext);
      } else {
        return false;
      }
    }
  }
  /**
   * Enable error handler to mute expected messages
   *
   * @return void
   */
  public static function muteExpectedErrors()
  {
    /*
      error muting is done because some people implemented custom error_handlers using
      http://php.net/set_error_handler and for some reason did not understand the following paragraph:
        It is important to remember that the standard PHP error handler is completely bypassed for the
        error types specified by error_types unless the callback function returns FALSE.
        error_reporting() settings will have no effect and your error handler will be called regardless -
        however you are still able to read the current value of error_reporting and act appropriately.
        Of particular note is that this value will be 0 if the statement that caused the error was
        prepended by the @ error-control operator.
      Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include
        - @filemtime() is almost twice as fast as using an additional file_exists()
        - between file_exists() and filemtime() a possible race condition is opened,
         which does not exist using the simple @filemtime() approach.
    */
    $error_handler = array('Smarty', 'mutingErrorHandler');
    $previous = set_error_handler($error_handler);
    // avoid dead loops
    if ($previous !== $error_handler) {
      Smarty::$_previous_error_handler = $previous;
    }
  }
  /**
   * Disable error handler muting expected messages
   *
   * @return void
   */
  public static function unmuteExpectedErrors()
  {
    restore_error_handler();
  }
}
// Check if we're running on windows
Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
// let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8
if (Smarty::$_CHARSET !== 'UTF-8') {
  Smarty::$_UTF8_MODIFIER = '';
}
/**
 * Smarty exception class
 *
 * @package Smarty
 */
class SmartyException extends Exception
{
  public static $escape = false;
  public function __toString()
  {
    return ' --> Smarty: ' . (self::$escape &#63; htmlentities($this->message) : $this->message) . ' <-- ';
  }
}
/**
 * Smarty compiler exception class
 *
 * @package Smarty
 */
class SmartyCompilerException extends SmartyException
{
  public function __toString()
  {
    return ' --> Smarty Compiler: ' . $this->message . ' <-- ';
  }
  /**
   * The line number of the template error
   *
   * @type int|null
   */
  public $line = null;
  /**
   * The template source snippet relating to the error
   *
   * @type string|null
   */
  public $source = null;
  /**
   * The raw text of the error message
   *
   * @type string|null
   */
  public $desc = null;
  /**
   * The resource identifier or template name
   *
   * @type string|null
   */
  public $template = null;
}
/**
 * Autoloader
 */
function smartyAutoload($class)
{
  $_class = strtolower($class);
  static $_classes = array(
    'smarty_config_source'        => true,
    'smarty_config_compiled'       => true,
    'smarty_security'          => true,
    'smarty_cacheresource'        => true,
    'smarty_cacheresource_custom'    => true,
    'smarty_cacheresource_keyvaluestore' => true,
    'smarty_resource'          => true,
    'smarty_resource_custom'       => true,
    'smarty_resource_uncompiled'     => true,
    'smarty_resource_recompiled'     => true,
  );
  if (!strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) {
    include SMARTY_SYSPLUGINS_DIR . $_class . '.php';
  }
}
<&#63;php
/**
 * Project:   Smarty: the PHP compiling template engine
 * File:    Smarty.class.php
 * SVN:     $Id: Smarty.class.php 4848 2014-06-08 18:12:09Z Uwe.Tews@googlemail.com $
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 * For questions, help, comments, discussion, etc., please join the
 * Smarty mailing list. Send a blank e-mail to
 * smarty-discussion-subscribe@googlegroups.com
 *
 * @link   http://www.smarty.net/
 * @copyright 2008 New Digital Group, Inc.
 * @author  Monte Ohrt <monte at ohrt dot com>
 * @author  Uwe Tews
 * @author  Rodney Rehm
 * @package  Smarty
 * @version  3.1.19
 */
/**
 * define shorthand directory separator constant
 */
if (!defined('DS')) {
  define('DS', DIRECTORY_SEPARATOR);
}
/**
 * set SMARTY_DIR to absolute path to Smarty library files.
 * Sets SMARTY_DIR only if user application has not already defined it.
 */
if (!defined('SMARTY_DIR')) {
  define('SMARTY_DIR', dirname(__FILE__) . DS);
}
/**
 * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins.
 * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it.
 */
if (!defined('SMARTY_SYSPLUGINS_DIR')) {
  define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DS);
}
if (!defined('SMARTY_PLUGINS_DIR')) {
  define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS);
}
if (!defined('SMARTY_MBSTRING')) {
  define('SMARTY_MBSTRING', function_exists('mb_split'));
}
if (!defined('SMARTY_RESOURCE_CHAR_SET')) {
  // UTF-8 can only be done properly when mbstring is available!
  /**
   * @deprecated in favor of Smarty::$_CHARSET
   */
  define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING &#63; 'UTF-8' : 'ISO-8859-1');
}
if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) {
  /**
   * @deprecated in favor of Smarty::$_DATE_FORMAT
   */
  define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y');
}
/**
 * register the class autoloader
 */
if (!defined('SMARTY_SPL_AUTOLOAD')) {
  define('SMARTY_SPL_AUTOLOAD', 0);
}
if (SMARTY_SPL_AUTOLOAD && set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false) {
  $registeredAutoLoadFunctions = spl_autoload_functions();
  if (!isset($registeredAutoLoadFunctions['spl_autoload'])) {
    spl_autoload_register();
  }
} else {
  spl_autoload_register('smartyAutoload');
}
/**
 * Load always needed external class files
 */
include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php';
include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php';
include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php';
include_once SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php';
include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_resource_file.php';
include_once SMARTY_SYSPLUGINS_DIR . 'smarty_cacheresource.php';
include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_cacheresource_file.php';
/**
 * This is the main Smarty class
 *
 * @package Smarty
 */
class Smarty extends Smarty_Internal_TemplateBase
{
  /**#@+
   * constant definitions
   */
  /**
   * smarty version
   */
  const SMARTY_VERSION = 'Smarty-3.1.19';
  /**
   * define variable scopes
   */
  const SCOPE_LOCAL = 0;
  const SCOPE_PARENT = 1;
  const SCOPE_ROOT = 2;
  const SCOPE_GLOBAL = 3;
  /**
   * define caching modes
   */
  const CACHING_OFF = 0;
  const CACHING_LIFETIME_CURRENT = 1;
  const CACHING_LIFETIME_SAVED = 2;
  /**
   * define constant for clearing cache files be saved expiration datees
   */
  const CLEAR_EXPIRED = - 1;
  /**
   * define compile check modes
   */
  const COMPILECHECK_OFF = 0;
  const COMPILECHECK_ON = 1;
  const COMPILECHECK_CACHEMISS = 2;
  /**
   * modes for handling of "<&#63;php ... &#63;>" tags in templates.
   */
  const PHP_PASSTHRU = 0; //-> print tags as plain text
  const PHP_QUOTE = 1; //-> escape tags as entities
  const PHP_REMOVE = 2; //-> escape tags as entities
  const PHP_ALLOW = 3; //-> escape tags as entities
  /**
   * filter types
   */
  const FILTER_POST = 'post';
  const FILTER_PRE = 'pre';
  const FILTER_OUTPUT = 'output';
  const FILTER_VARIABLE = 'variable';
  /**
   * plugin types
   */
  const PLUGIN_FUNCTION = 'function';
  const PLUGIN_BLOCK = 'block';
  const PLUGIN_COMPILER = 'compiler';
  const PLUGIN_MODIFIER = 'modifier';
  const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler';
  /**#@-*/
  /**
   * assigned global tpl vars
   */
  public static $global_tpl_vars = array();
  /**
   * error handler returned by set_error_hanlder() in Smarty::muteExpectedErrors()
   */
  public static $_previous_error_handler = null;
  /**
   * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors()
   */
  public static $_muted_directories = array();
  /**
   * Flag denoting if Multibyte String functions are available
   */
  public static $_MBSTRING = SMARTY_MBSTRING;
  /**
   * The character set to adhere to (e.g. "UTF-8")
   */
  public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET;
  /**
   * The date format to be used internally
   * (accepts date() and strftime())
   */
  public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT;
  /**
   * Flag denoting if PCRE should run in UTF-8 mode
   */
  public static $_UTF8_MODIFIER = 'u';
  /**
   * Flag denoting if operating system is windows
   */
  public static $_IS_WINDOWS = false;
  /**#@+
   * variables
   */
  /**
   * auto literal on delimiters with whitspace
   *
   * @var boolean
   */
  public $auto_literal = true;
  /**
   * display error on not assigned variables
   *
   * @var boolean
   */
  public $error_unassigned = false;
  /**
   * look up relative filepaths in include_path
   *
   * @var boolean
   */
  public $use_include_path = false;
  /**
   * template directory
   *
   * @var array
   */
  private $template_dir = array();
  /**
   * joined template directory string used in cache keys
   *
   * @var string
   */
  public $joined_template_dir = null;
  /**
   * joined config directory string used in cache keys
   *
   * @var string
   */
  public $joined_config_dir = null;
  /**
   * default template handler
   *
   * @var callable
   */
  public $default_template_handler_func = null;
  /**
   * default config handler
   *
   * @var callable
   */
  public $default_config_handler_func = null;
  /**
   * default plugin handler
   *
   * @var callable
   */
  public $default_plugin_handler_func = null;
  /**
   * compile directory
   *
   * @var string
   */
  private $compile_dir = null;
  /**
   * plugins directory
   *
   * @var array
   */
  private $plugins_dir = array();
  /**
   * cache directory
   *
   * @var string
   */
  private $cache_dir = null;
  /**
   * config directory
   *
   * @var array
   */
  private $config_dir = array();
  /**
   * force template compiling&#63;
   *
   * @var boolean
   */
  public $force_compile = false;
  /**
   * check template for modifications&#63;
   *
   * @var boolean
   */
  public $compile_check = true;
  /**
   * use sub dirs for compiled/cached files&#63;
   *
   * @var boolean
   */
  public $use_sub_dirs = false;
  /**
   * allow ambiguous resources (that are made unique by the resource handler)
   *
   * @var boolean
   */
  public $allow_ambiguous_resources = false;
  /**
   * caching enabled
   *
   * @var boolean
   */
  public $caching = false;
  /**
   * merge compiled includes
   *
   * @var boolean
   */
  public $merge_compiled_includes = false;
  /**
   * template inheritance merge compiled includes
   *
   * @var boolean
   */
  public $inheritance_merge_compiled_includes = true;
  /**
   * cache lifetime in seconds
   *
   * @var integer
   */
  public $cache_lifetime = 3600;
  /**
   * force cache file creation
   *
   * @var boolean
   */
  public $force_cache = false;
  /**
   * Set this if you want different sets of cache files for the same
   * templates.
   *
   * @var string
   */
  public $cache_id = null;
  /**
   * Set this if you want different sets of compiled files for the same
   * templates.
   *
   * @var string
   */
  public $compile_id = null;
  /**
   * template left-delimiter
   *
   * @var string
   */
  public $left_delimiter = "{";
  /**
   * template right-delimiter
   *
   * @var string
   */
  public $right_delimiter = "}";
  /**#@+
   * security
   */
  /**
   * class name
   * This should be instance of Smarty_Security.
   *
   * @var string
   * @see Smarty_Security
   */
  public $security_class = 'Smarty_Security';
  /**
   * implementation of security class
   *
   * @var Smarty_Security
   */
  public $security_policy = null;
  /**
   * controls handling of PHP-blocks
   *
   * @var integer
   */
  public $php_handling = self::PHP_PASSTHRU;
  /**
   * controls if the php template file resource is allowed
   *
   * @var bool
   */
  public $allow_php_templates = false;
  /**
   * Should compiled-templates be prevented from being called directly&#63;
   * {@internal
   * Currently used by Smarty_Internal_Template only.
   * }}
   *
   * @var boolean
   */
  public $direct_access_security = true;
  /**#@-*/
  /**
   * debug mode
   * Setting this to true enables the debug-console.
   *
   * @var boolean
   */
  public $debugging = false;
  /**
   * This determines if debugging is enable-able from the browser.
   * <ul>
   * <li>NONE => no debugging control allowed</li>
   * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
   * </ul>
   *
   * @var string
   */
  public $debugging_ctrl = 'NONE';
  /**
   * Name of debugging URL-param.
   * Only used when $debugging_ctrl is set to 'URL'.
   * The name of the URL-parameter that activates debugging.
   *
   * @var type
   */
  public $smarty_debug_id = 'SMARTY_DEBUG';
  /**
   * Path of debug template.
   *
   * @var string
   */
  public $debug_tpl = null;
  /**
   * When set, smarty uses this value as error_reporting-level.
   *
   * @var int
   */
  public $error_reporting = null;
  /**
   * Internal flag for getTags()
   *
   * @var boolean
   */
  public $get_used_tags = false;
  /**#@+
   * config var settings
   */
  /**
   * Controls whether variables with the same name overwrite each other.
   *
   * @var boolean
   */
  public $config_overwrite = true;
  /**
   * Controls whether config values of on/true/yes and off/false/no get converted to boolean.
   *
   * @var boolean
   */
  public $config_booleanize = true;
  /**
   * Controls whether hidden config sections/vars are read from the file.
   *
   * @var boolean
   */
  public $config_read_hidden = false;
  /**#@-*/
  /**#@+
   * resource locking
   */
  /**
   * locking concurrent compiles
   *
   * @var boolean
   */
  public $compile_locking = true;
  /**
   * Controls whether cache resources should emply locking mechanism
   *
   * @var boolean
   */
  public $cache_locking = false;
  /**
   * seconds to wait for acquiring a lock before ignoring the write lock
   *
   * @var float
   */
  public $locking_timeout = 10;
  /**#@-*/
  /**
   * global template functions
   *
   * @var array
   */
  public $template_functions = array();
  /**
   * resource type used if none given
   * Must be an valid key of $registered_resources.
   *
   * @var string
   */
  public $default_resource_type = 'file';
  /**
   * caching type
   * Must be an element of $cache_resource_types.
   *
   * @var string
   */
  public $caching_type = 'file';
  /**
   * internal config properties
   *
   * @var array
   */
  public $properties = array();
  /**
   * config type
   *
   * @var string
   */
  public $default_config_type = 'file';
  /**
   * cached template objects
   *
   * @var array
   */
  public $template_objects = array();
  /**
   * check If-Modified-Since headers
   *
   * @var boolean
   */
  public $cache_modified_check = false;
  /**
   * registered plugins
   *
   * @var array
   */
  public $registered_plugins = array();
  /**
   * plugin search order
   *
   * @var array
   */
  public $plugin_search_order = array('function', 'block', 'compiler', 'class');
  /**
   * registered objects
   *
   * @var array
   */
  public $registered_objects = array();
  /**
   * registered classes
   *
   * @var array
   */
  public $registered_classes = array();
  /**
   * registered filters
   *
   * @var array
   */
  public $registered_filters = array();
  /**
   * registered resources
   *
   * @var array
   */
  public $registered_resources = array();
  /**
   * resource handler cache
   *
   * @var array
   */
  public $_resource_handlers = array();
  /**
   * registered cache resources
   *
   * @var array
   */
  public $registered_cache_resources = array();
  /**
   * cache resource handler cache
   *
   * @var array
   */
  public $_cacheresource_handlers = array();
  /**
   * autoload filter
   *
   * @var array
   */
  public $autoload_filters = array();
  /**
   * default modifier
   *
   * @var array
   */
  public $default_modifiers = array();
  /**
   * autoescape variable output
   *
   * @var boolean
   */
  public $escape_html = false;
  /**
   * global internal smarty vars
   *
   * @var array
   */
  public static $_smarty_vars = array();
  /**
   * start time for execution time calculation
   *
   * @var int
   */
  public $start_time = 0;
  /**
   * default file permissions
   *
   * @var int
   */
  public $_file_perms = 0644;
  /**
   * default dir permissions
   *
   * @var int
   */
  public $_dir_perms = 0771;
  /**
   * block tag hierarchy
   *
   * @var array
   */
  public $_tag_stack = array();
  /**
   * self pointer to Smarty object
   *
   * @var Smarty
   */
  public $smarty;
  /**
   * required by the compiler for BC
   *
   * @var string
   */
  public $_current_file = null;
  /**
   * internal flag to enable parser debugging
   *
   * @var bool
   */
  public $_parserdebug = false;
  /**
   * Saved parameter of merged templates during compilation
   *
   * @var array
   */
  public $merged_templates_func = array();
  /**#@-*/
  /**
   * Initialize new Smarty object
   */
  public function __construct()
  {
    // selfpointer needed by some other class methods
    $this->smarty = $this;
    if (is_callable('mb_internal_encoding')) {
      mb_internal_encoding(Smarty::$_CHARSET);
    }
    $this->start_time = microtime(true);
    // set default dirs
    $this->setTemplateDir('.' . DS . 'templates' . DS)
      ->setCompileDir('.' . DS . 'templates_c' . DS)
      ->setPluginsDir(SMARTY_PLUGINS_DIR)
      ->setCacheDir('.' . DS . 'cache' . DS)
      ->setConfigDir('.' . DS . 'configs' . DS);
    $this->debug_tpl = 'file:' . dirname(__FILE__) . '/debug.tpl';
    if (isset($_SERVER['SCRIPT_NAME'])) {
      $this->assignGlobal('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']);
    }
  }
  /**
   * Class destructor
   */
  public function __destruct()
  {
    // intentionally left blank
  }
  /**
   * <<magic>> set selfpointer on cloned object
   */
  public function __clone()
  {
    $this->smarty = $this;
  }
  /**
   * <<magic>> Generic getter.
   * Calls the appropriate getter function.
   * Issues an E_USER_NOTICE if no valid getter is found.
   *
   * @param string $name property name
   *
   * @return mixed
   */
  public function __get($name)
  {
    $allowed = array(
      'template_dir' => 'getTemplateDir',
      'config_dir'  => 'getConfigDir',
      'plugins_dir' => 'getPluginsDir',
      'compile_dir' => 'getCompileDir',
      'cache_dir'  => 'getCacheDir',
    );
    if (isset($allowed[$name])) {
      return $this->{$allowed[$name]}();
    } else {
      trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
    }
  }
  /**
   * <<magic>> Generic setter.
   * Calls the appropriate setter function.
   * Issues an E_USER_NOTICE if no valid setter is found.
   *
   * @param string $name property name
   * @param mixed $value parameter passed to setter
   */
  public function __set($name, $value)
  {
    $allowed = array(
      'template_dir' => 'setTemplateDir',
      'config_dir'  => 'setConfigDir',
      'plugins_dir' => 'setPluginsDir',
      'compile_dir' => 'setCompileDir',
      'cache_dir'  => 'setCacheDir',
    );
    if (isset($allowed[$name])) {
      $this->{$allowed[$name]}($value);
    } else {
      trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
    }
  }
  /**
   * Check if a template resource exists
   *
   * @param string $resource_name template name
   *
   * @return boolean status
   */
  public function templateExists($resource_name)
  {
    // create template object
    $save = $this->template_objects;
    $tpl = new $this->template_class($resource_name, $this);
    // check if it does exists
    $result = $tpl->source->exists;
    $this->template_objects = $save;
    return $result;
  }
  /**
   * Returns a single or all global variables
   *
   * @param string $varname variable name or null
   *
   * @return string variable value or or array of variables
   */
  public function getGlobal($varname = null)
  {
    if (isset($varname)) {
      if (isset(self::$global_tpl_vars[$varname])) {
        return self::$global_tpl_vars[$varname]->value;
      } else {
        return '';
      }
    } else {
      $_result = array();
      foreach (self::$global_tpl_vars AS $key => $var) {
        $_result[$key] = $var->value;
      }
      return $_result;
    }
  }
  /**
   * Empty cache folder
   *
   * @param integer $exp_time expiration time
   * @param string $type   resource type
   *
   * @return integer number of cache files deleted
   */
  public function clearAllCache($exp_time = null, $type = null)
  {
    // load cache resource and call clearAll
    $_cache_resource = Smarty_CacheResource::load($this, $type);
    Smarty_CacheResource::invalidLoadedCache($this);
    return $_cache_resource->clearAll($this, $exp_time);
  }
  /**
   * Empty cache for a specific template
   *
   * @param string $template_name template name
   * @param string $cache_id   cache id
   * @param string $compile_id  compile id
   * @param integer $exp_time   expiration time
   * @param string $type     resource type
   *
   * @return integer number of cache files deleted
   */
  public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
  {
    // load cache resource and call clear
    $_cache_resource = Smarty_CacheResource::load($this, $type);
    Smarty_CacheResource::invalidLoadedCache($this);
    return $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time);
  }
  /**
   * Loads security class and enables security
   *
   * @param string|Smarty_Security $security_class if a string is used, it must be class-name
   *
   * @return Smarty         current Smarty instance for chaining
   * @throws SmartyException    when an invalid class name is provided
   */
  public function enableSecurity($security_class = null)
  {
    if ($security_class instanceof Smarty_Security) {
      $this->security_policy = $security_class;
      return $this;
    } elseif (is_object($security_class)) {
      throw new SmartyException("Class '" . get_class($security_class) . "' must extend Smarty_Security.");
    }
    if ($security_class == null) {
      $security_class = $this->security_class;
    }
    if (!class_exists($security_class)) {
      throw new SmartyException("Security class '$security_class' is not defined");
    } elseif ($security_class !== 'Smarty_Security' && !is_subclass_of($security_class, 'Smarty_Security')) {
      throw new SmartyException("Class '$security_class' must extend Smarty_Security.");
    } else {
      $this->security_policy = new $security_class($this);
    }
    return $this;
  }
  /**
   * Disable security
   *
   * @return Smarty current Smarty instance for chaining
   */
  public function disableSecurity()
  {
    $this->security_policy = null;
    return $this;
  }
  /**
   * Set template directory
   *
   * @param string|array $template_dir directory(s) of template sources
   *
   * @return Smarty    current Smarty instance for chaining
   */
  public function setTemplateDir($template_dir)
  {
    $this->template_dir = array();
    foreach ((array) $template_dir as $k => $v) {
      $this->template_dir[$k] = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS;
    }
    $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir);
    return $this;
  }
  /**
   * Add template directory(s)
   *
   * @param string|array $template_dir directory(s) of template sources
   * @param string    $key     of the array element to assign the template dir to
   *
   * @return Smarty     current Smarty instance for chaining
   * @throws SmartyException when the given template directory is not valid
   */
  public function addTemplateDir($template_dir, $key = null)
  {
    // make sure we're dealing with an array
    $this->template_dir = (array) $this->template_dir;
    if (is_array($template_dir)) {
      foreach ($template_dir as $k => $v) {
        $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS;
        if (is_int($k)) {
          // indexes are not merged but appended
          $this->template_dir[] = $v;
        } else {
          // string indexes are overridden
          $this->template_dir[$k] = $v;
        }
      }
    } else {
      $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($template_dir, '/\\')) . DS;
      if ($key !== null) {
        // override directory at specified index
        $this->template_dir[$key] = $v;
      } else {
        // append new directory
        $this->template_dir[] = $v;
      }
    }
    $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir);
    return $this;
  }
  /**
   * Get template directories
   *
   * @param mixed $index index of directory to get, null to get all
   *
   * @return array|string list of template directories, or directory of $index
   */
  public function getTemplateDir($index = null)
  {
    if ($index !== null) {
      return isset($this->template_dir[$index]) &#63; $this->template_dir[$index] : null;
    }
    return (array) $this->template_dir;
  }
  /**
   * Set config directory
   *
   * @param $config_dir
   *
   * @return Smarty    current Smarty instance for chaining
   */
  public function setConfigDir($config_dir)
  {
    $this->config_dir = array();
    foreach ((array) $config_dir as $k => $v) {
      $this->config_dir[$k] = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS;
    }
    $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir);
    return $this;
  }
  /**
   * Add config directory(s)
   *
   * @param string|array    $config_dir directory(s) of config sources
   * @param mixed $key    key of the array element to assign the config dir to
   *
   * @return Smarty current Smarty instance for chaining
   */
  public function addConfigDir($config_dir, $key = null)
  {
    // make sure we're dealing with an array
    $this->config_dir = (array) $this->config_dir;
    if (is_array($config_dir)) {
      foreach ($config_dir as $k => $v) {
        $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS;
        if (is_int($k)) {
          // indexes are not merged but appended
          $this->config_dir[] = $v;
        } else {
          // string indexes are overridden
          $this->config_dir[$k] = $v;
        }
      }
    } else {
      $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($config_dir, '/\\')) . DS;
      if ($key !== null) {
        // override directory at specified index
        $this->config_dir[$key] = rtrim($v, '/\\') . DS;
      } else {
        // append new directory
        $this->config_dir[] = rtrim($v, '/\\') . DS;
      }
    }
    $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir);
    return $this;
  }
  /**
   * Get config directory
   *
   * @param mixed $index index of directory to get, null to get all
   *
   * @return array|string configuration directory
   */
  public function getConfigDir($index = null)
  {
    if ($index !== null) {
      return isset($this->config_dir[$index]) &#63; $this->config_dir[$index] : null;
    }
    return (array) $this->config_dir;
  }
  /**
   * Set plugins directory
   *
   * @param string|array $plugins_dir directory(s) of plugins
   *
   * @return Smarty    current Smarty instance for chaining
   */
  public function setPluginsDir($plugins_dir)
  {
    $this->plugins_dir = array();
    foreach ((array) $plugins_dir as $k => $v) {
      $this->plugins_dir[$k] = rtrim($v, '/\\') . DS;
    }
    return $this;
  }
  /**
   * Adds directory of plugin files
   *
   * @param $plugins_dir
   *
   * @return Smarty current Smarty instance for chaining
   */
  public function addPluginsDir($plugins_dir)
  {
    // make sure we're dealing with an array
    $this->plugins_dir = (array) $this->plugins_dir;
    if (is_array($plugins_dir)) {
      foreach ($plugins_dir as $k => $v) {
        if (is_int($k)) {
          // indexes are not merged but appended
          $this->plugins_dir[] = rtrim($v, '/\\') . DS;
        } else {
          // string indexes are overridden
          $this->plugins_dir[$k] = rtrim($v, '/\\') . DS;
        }
      }
    } else {
      // append new directory
      $this->plugins_dir[] = rtrim($plugins_dir, '/\\') . DS;
    }
    $this->plugins_dir = array_unique($this->plugins_dir);
    return $this;
  }
  /**
   * Get plugin directories
   *
   * @return array list of plugin directories
   */
  public function getPluginsDir()
  {
    return (array) $this->plugins_dir;
  }
  /**
   * Set compile directory
   *
   * @param string $compile_dir directory to store compiled templates in
   *
   * @return Smarty current Smarty instance for chaining
   */
  public function setCompileDir($compile_dir)
  {
    $this->compile_dir = rtrim($compile_dir, '/\\') . DS;
    if (!isset(Smarty::$_muted_directories[$this->compile_dir])) {
      Smarty::$_muted_directories[$this->compile_dir] = null;
    }
    return $this;
  }
  /**
   * Get compiled directory
   *
   * @return string path to compiled templates
   */
  public function getCompileDir()
  {
    return $this->compile_dir;
  }
  /**
   * Set cache directory
   *
   * @param string $cache_dir directory to store cached templates in
   *
   * @return Smarty current Smarty instance for chaining
   */
  public function setCacheDir($cache_dir)
  {
    $this->cache_dir = rtrim($cache_dir, '/\\') . DS;
    if (!isset(Smarty::$_muted_directories[$this->cache_dir])) {
      Smarty::$_muted_directories[$this->cache_dir] = null;
    }
    return $this;
  }
  /**
   * Get cache directory
   *
   * @return string path of cache directory
   */
  public function getCacheDir()
  {
    return $this->cache_dir;
  }
  /**
   * Set default modifiers
   *
   * @param array|string $modifiers modifier or list of modifiers to set
   *
   * @return Smarty    current Smarty instance for chaining
   */
  public function setDefaultModifiers($modifiers)
  {
    $this->default_modifiers = (array) $modifiers;
    return $this;
  }
  /**
   * Add default modifiers
   *
   * @param array|string $modifiers modifier or list of modifiers to add
   *
   * @return Smarty    current Smarty instance for chaining
   */
  public function addDefaultModifiers($modifiers)
  {
    if (is_array($modifiers)) {
      $this->default_modifiers = array_merge($this->default_modifiers, $modifiers);
    } else {
      $this->default_modifiers[] = $modifiers;
    }
    return $this;
  }
  /**
   * Get default modifiers
   *
   * @return array list of default modifiers
   */
  public function getDefaultModifiers()
  {
    return $this->default_modifiers;
  }
  /**
   * Set autoload filters
   *
   * @param array $filters filters to load automatically
   * @param string $type  "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types
   *
   * @return Smarty current Smarty instance for chaining
   */
  public function setAutoloadFilters($filters, $type = null)
  {
    if ($type !== null) {
      $this->autoload_filters[$type] = (array) $filters;
    } else {
      $this->autoload_filters = (array) $filters;
    }
    return $this;
  }
  /**
   * Add autoload filters
   *
   * @param array $filters filters to load automatically
   * @param string $type  "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types
   *
   * @return Smarty current Smarty instance for chaining
   */
  public function addAutoloadFilters($filters, $type = null)
  {
    if ($type !== null) {
      if (!empty($this->autoload_filters[$type])) {
        $this->autoload_filters[$type] = array_merge($this->autoload_filters[$type], (array) $filters);
      } else {
        $this->autoload_filters[$type] = (array) $filters;
      }
    } else {
      foreach ((array) $filters as $key => $value) {
        if (!empty($this->autoload_filters[$key])) {
          $this->autoload_filters[$key] = array_merge($this->autoload_filters[$key], (array) $value);
        } else {
          $this->autoload_filters[$key] = (array) $value;
        }
      }
    }
    return $this;
  }
  /**
   * Get autoload filters
   *
   * @param string $type type of filter to get autoloads for. Defaults to all autoload filters
   *
   * @return array array( 'type1' => array( 'filter1', 'filter2', … ) ) or array( 'filter1', 'filter2', …) if $type was specified
   */
  public function getAutoloadFilters($type = null)
  {
    if ($type !== null) {
      return isset($this->autoload_filters[$type]) &#63; $this->autoload_filters[$type] : array();
    }
    return $this->autoload_filters;
  }
  /**
   * return name of debugging template
   *
   * @return string
   */
  public function getDebugTemplate()
  {
    return $this->debug_tpl;
  }
  /**
   * set the debug template
   *
   * @param string $tpl_name
   *
   * @return Smarty     current Smarty instance for chaining
   * @throws SmartyException if file is not readable
   */
  public function setDebugTemplate($tpl_name)
  {
    if (!is_readable($tpl_name)) {
      throw new SmartyException("Unknown file '{$tpl_name}'");
    }
    $this->debug_tpl = $tpl_name;
    return $this;
  }
  /**
   * creates a template object
   *
   * @param string $template  the resource handle of the template file
   * @param mixed  $cache_id  cache id to be used with this template
   * @param mixed  $compile_id compile id to be used with this template
   * @param object $parent   next higher level of Smarty variables
   * @param boolean $do_clone  flag is Smarty object shall be cloned
   *
   * @return object template object
   */
  public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true)
  {
    if ($cache_id !== null && (is_object($cache_id) || is_array($cache_id))) {
      $parent = $cache_id;
      $cache_id = null;
    }
    if ($parent !== null && is_array($parent)) {
      $data = $parent;
      $parent = null;
    } else {
      $data = null;
    }
    // default to cache_id and compile_id of Smarty object
    $cache_id = $cache_id === null &#63; $this->cache_id : $cache_id;
    $compile_id = $compile_id === null &#63; $this->compile_id : $compile_id;
    // already in template cache&#63;
    if ($this->allow_ambiguous_resources) {
      $_templateId = Smarty_Resource::getUniqueTemplateName($this, $template) . $cache_id . $compile_id;
    } else {
      $_templateId = $this->joined_template_dir . '#' . $template . $cache_id . $compile_id;
    }
    if (isset($_templateId[150])) {
      $_templateId = sha1($_templateId);
    }
    if ($do_clone) {
      if (isset($this->template_objects[$_templateId])) {
        // return cached template object
        $tpl = clone $this->template_objects[$_templateId];
        $tpl->smarty = clone $tpl->smarty;
        $tpl->parent = $parent;
        $tpl->tpl_vars = array();
        $tpl->config_vars = array();
      } else {
        $tpl = new $this->template_class($template, clone $this, $parent, $cache_id, $compile_id);
      }
    } else {
      if (isset($this->template_objects[$_templateId])) {
        // return cached template object
        $tpl = $this->template_objects[$_templateId];
        $tpl->parent = $parent;
        $tpl->tpl_vars = array();
        $tpl->config_vars = array();
      } else {
        $tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id);
      }
    }
    // fill data if present
    if (!empty($data) && is_array($data)) {
      // set up variable values
      foreach ($data as $_key => $_val) {
        $tpl->tpl_vars[$_key] = new Smarty_variable($_val);
      }
    }
    return $tpl;
  }
  /**
   * Takes unknown classes and loads plugin files for them
   * class name format: Smarty_PluginType_PluginName
   * plugin filename format: plugintype.pluginname.php
   *
   * @param string $plugin_name class plugin name to load
   * @param bool  $check    check if already loaded
   *
   * @throws SmartyException
   * @return string |boolean filepath of loaded file or false
   */
  public function loadPlugin($plugin_name, $check = true)
  {
    // if function or class exists, exit silently (already loaded)
    if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) {
      return true;
    }
    // Plugin name is expected to be: Smarty_[Type]_[Name]
    $_name_parts = explode('_', $plugin_name, 3);
    // class name must have three parts to be valid plugin
    // count($_name_parts) < 3 === !isset($_name_parts[2])
    if (!isset($_name_parts[2]) || strtolower($_name_parts[0]) !== 'smarty') {
      throw new SmartyException("plugin {$plugin_name} is not a valid name format");
    }
    // if type is "internal", get plugin from sysplugins
    if (strtolower($_name_parts[1]) == 'internal') {
      $file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php';
      if (file_exists($file)) {
        require_once($file);
        return $file;
      } else {
        return false;
      }
    }
    // plugin filename is expected to be: [type].[name].php
    $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php";
    $_stream_resolve_include_path = function_exists('stream_resolve_include_path');
    // loop through plugin dirs and find the plugin
    foreach ($this->getPluginsDir() as $_plugin_dir) {
      $names = array(
        $_plugin_dir . $_plugin_filename,
        $_plugin_dir . strtolower($_plugin_filename),
      );
      foreach ($names as $file) {
        if (file_exists($file)) {
          require_once($file);
          return $file;
        }
        if ($this->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
          // try PHP include_path
          if ($_stream_resolve_include_path) {
            $file = stream_resolve_include_path($file);
          } else {
            $file = Smarty_Internal_Get_Include_Path::getIncludePath($file);
          }
          if ($file !== false) {
            require_once($file);
            return $file;
          }
        }
      }
    }
    // no plugin loaded
    return false;
  }
  /**
   * Compile all template files
   *
   * @param string $extension   file extension
   * @param bool  $force_compile force all to recompile
   * @param int  $time_limit
   * @param int  $max_errors
   *
   * @return integer number of template files recompiled
   */
  public function compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
  {
    return Smarty_Internal_Utility::compileAllTemplates($extension, $force_compile, $time_limit, $max_errors, $this);
  }
  /**
   * Compile all config files
   *
   * @param string $extension   file extension
   * @param bool  $force_compile force all to recompile
   * @param int  $time_limit
   * @param int  $max_errors
   *
   * @return integer number of template files recompiled
   */
  public function compileAllConfig($extension = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null)
  {
    return Smarty_Internal_Utility::compileAllConfig($extension, $force_compile, $time_limit, $max_errors, $this);
  }
  /**
   * Delete compiled template file
   *
   * @param string $resource_name template name
   * @param string $compile_id  compile id
   * @param integer $exp_time   expiration time
   *
   * @return integer number of template files deleted
   */
  public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
  {
    return Smarty_Internal_Utility::clearCompiledTemplate($resource_name, $compile_id, $exp_time, $this);
  }
  /**
   * Return array of tag/attributes of all tags used by an template
   *
   * @param Smarty_Internal_Template $template
   *
   * @return array of tag/attributes
   */
  public function getTags(Smarty_Internal_Template $template)
  {
    return Smarty_Internal_Utility::getTags($template);
  }
  /**
   * Run installation test
   *
   * @param array $errors Array to write errors into, rather than outputting them
   *
   * @return boolean true if setup is fine, false if something is wrong
   */
  public function testInstall(&$errors = null)
  {
    return Smarty_Internal_Utility::testInstall($this, $errors);
  }
  /**
   * Error Handler to mute expected messages
   *
   * @link http://php.net/set_error_handler
   *
   * @param integer $errno Error level
   * @param     $errstr
   * @param     $errfile
   * @param     $errline
   * @param     $errcontext
   *
   * @return boolean
   */
  public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext)
  {
    $_is_muted_directory = false;
    // add the SMARTY_DIR to the list of muted directories
    if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) {
      $smarty_dir = realpath(SMARTY_DIR);
      if ($smarty_dir !== false) {
        Smarty::$_muted_directories[SMARTY_DIR] = array(
          'file'  => $smarty_dir,
          'length' => strlen($smarty_dir),
        );
      }
    }
    // walk the muted directories and test against $errfile
    foreach (Smarty::$_muted_directories as $key => &$dir) {
      if (!$dir) {
        // resolve directory and length for speedy comparisons
        $file = realpath($key);
        if ($file === false) {
          // this directory does not exist, remove and skip it
          unset(Smarty::$_muted_directories[$key]);
          continue;
        }
        $dir = array(
          'file'  => $file,
          'length' => strlen($file),
        );
      }
      if (!strncmp($errfile, $dir['file'], $dir['length'])) {
        $_is_muted_directory = true;
        break;
      }
    }
    // pass to next error handler if this error did not occur inside SMARTY_DIR
    // or the error was within smarty but masked to be ignored
    if (!$_is_muted_directory || ($errno && $errno & error_reporting())) {
      if (Smarty::$_previous_error_handler) {
        return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline, $errcontext);
      } else {
        return false;
      }
    }
  }
  /**
   * Enable error handler to mute expected messages
   *
   * @return void
   */
  public static function muteExpectedErrors()
  {
    /*
      error muting is done because some people implemented custom error_handlers using
      http://php.net/set_error_handler and for some reason did not understand the following paragraph:
        It is important to remember that the standard PHP error handler is completely bypassed for the
        error types specified by error_types unless the callback function returns FALSE.
        error_reporting() settings will have no effect and your error handler will be called regardless -
        however you are still able to read the current value of error_reporting and act appropriately.
        Of particular note is that this value will be 0 if the statement that caused the error was
        prepended by the @ error-control operator.
      Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include
        - @filemtime() is almost twice as fast as using an additional file_exists()
        - between file_exists() and filemtime() a possible race condition is opened,
         which does not exist using the simple @filemtime() approach.
    */
    $error_handler = array('Smarty', 'mutingErrorHandler');
    $previous = set_error_handler($error_handler);
    // avoid dead loops
    if ($previous !== $error_handler) {
      Smarty::$_previous_error_handler = $previous;
    }
  }
  /**
   * Disable error handler muting expected messages
   *
   * @return void
   */
  public static function unmuteExpectedErrors()
  {
    restore_error_handler();
  }
}
// Check if we're running on windows
Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
// let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8
if (Smarty::$_CHARSET !== 'UTF-8') {
  Smarty::$_UTF8_MODIFIER = '';
}
/**
 * Smarty exception class
 *
 * @package Smarty
 */
class SmartyException extends Exception
{
  public static $escape = false;
  public function __toString()
  {
    return ' --> Smarty: ' . (self::$escape &#63; htmlentities($this->message) : $this->message) . ' <-- ';
  }
}
/**
 * Smarty compiler exception class
 *
 * @package Smarty
 */
class SmartyCompilerException extends SmartyException
{
  public function __toString()
  {
    return ' --> Smarty Compiler: ' . $this->message . ' <-- ';
  }
  /**
   * The line number of the template error
   *
   * @type int|null
   */
  public $line = null;
  /**
   * The template source snippet relating to the error
   *
   * @type string|null
   */
  public $source = null;
  /**
   * The raw text of the error message
   *
   * @type string|null
   */
  public $desc = null;
  /**
   * The resource identifier or template name
   *
   * @type string|null
   */
  public $template = null;
}
/**
 * Autoloader
 */
function smartyAutoload($class)
{
  $_class = strtolower($class);
  static $_classes = array(
    'smarty_config_source'        => true,
    'smarty_config_compiled'       => true,
    'smarty_security'          => true,
    'smarty_cacheresource'        => true,
    'smarty_cacheresource_custom'    => true,
    'smarty_cacheresource_keyvaluestore' => true,
    'smarty_resource'          => true,
    'smarty_resource_custom'       => true,
    'smarty_resource_uncompiled'     => true,
    'smarty_resource_recompiled'     => true,
  );
  if (!strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) {
    include SMARTY_SYSPLUGINS_DIR . $_class . '.php';
  }
}

更多关于Smarty相关内容感兴趣的读者可查看本站专题:《smarty模板入门基础教程》、《PHP模板技术总结》、《PHP基于pdo操作数据库技巧总结》、《PHP运算与运算符用法总结》、《PHP网络编程技巧总结》、《PHP基本语法入门教程》、《php面向对象程序设计入门教程》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家基于smarty模板的PHP程序设计有所帮助。

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace("&nbsp;","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

php怎么判断有没有小数点php怎么判断有没有小数点Apr 20, 2022 pm 08:12 PM

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

php怎么设置implode没有分隔符php怎么设置implode没有分隔符Apr 18, 2022 pm 05:39 PM

在PHP中,可以利用implode()函数的第一个参数来设置没有分隔符,该函数的第一个参数用于规定数组元素之间放置的内容,默认是空字符串,也可将第一个参数设置为空,语法为“implode(数组)”或者“implode("",数组)”。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。