/home/smartonegroup/public_html/veroserv/vendor/smarty/smarty/src/Smarty.php
<?php
namespace Smarty;
use FilesystemIterator;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Smarty\Cacheresource\File;
use Smarty\Extension\Base;
use Smarty\Extension\BCPluginsAdapter;
use Smarty\Extension\CallbackWrapper;
use Smarty\Extension\CoreExtension;
use Smarty\Extension\DefaultExtension;
use Smarty\Extension\ExtensionInterface;
use Smarty\Filter\Output\TrimWhitespace;
use Smarty\Runtime\CaptureRuntime;
use Smarty\Runtime\DefaultPluginHandlerRuntime;
use Smarty\Runtime\ForeachRuntime;
use Smarty\Runtime\InheritanceRuntime;
use Smarty\Runtime\TplFunctionRuntime;
/**
* Project: Smarty: the PHP compiling template engine
*
* 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 3.0 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
*
* @author Monte Ohrt <monte at ohrt dot com>
* @author Uwe Tews <uwe dot tews at gmail dot com>
* @author Rodney Rehm
* @author Simon Wisselink
*/
/**
* This is the main Smarty class
*/
class Smarty extends \Smarty\TemplateBase {
/**
* smarty version
*/
const SMARTY_VERSION = '5.4.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 dates
*/
const CLEAR_EXPIRED = -1;
/**
* define compile check modes
*/
const COMPILECHECK_OFF = 0;
const COMPILECHECK_ON = 1;
/**
* 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';
/**
* The character set to adhere to (defaults to "UTF-8")
*/
public static $_CHARSET = 'UTF-8';
/**
* The date format to be used internally
* (accepts date() and strftime())
*/
public static $_DATE_FORMAT = '%b %e, %Y';
/**
* 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;
/**
* auto literal on delimiters with whitespace
*
* @var boolean
*/
public $auto_literal = true;
/**
* display error on not assigned variables
*
* @var boolean
*/
public $error_unassigned = false;
/**
* flag if template_dir is normalized
*
* @var bool
*/
public $_templateDirNormalized = false;
/**
* joined template directory string used in cache keys
*
* @var string
*/
public $_joined_template_dir = null;
/**
* flag if config_dir is normalized
*
* @var bool
*/
public $_configDirNormalized = false;
/**
* 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
*/
private $default_plugin_handler_func = null;
/**
* flag if template_dir is normalized
*
* @var bool
*/
public $_compileDirNormalized = false;
/**
* flag if template_dir is normalized
*
* @var bool
*/
public $_cacheDirNormalized = false;
/**
* force template compiling?
*
* @var boolean
*/
public $force_compile = false;
/**
* use sub dirs for compiled/cached files?
*
* @var boolean
*/
public $use_sub_dirs = false;
/**
* merge compiled includes
*
* @var boolean
*/
public $merge_compiled_includes = false;
/**
* force cache file creation
*
* @var boolean
*/
public $force_cache = false;
/**
* template left-delimiter
*
* @var string
*/
private $left_delimiter = "{";
/**
* template right-delimiter
*
* @var string
*/
private $right_delimiter = "}";
/**
* array of strings which shall be treated as literal by compiler
*
* @var array string
*/
public $literals = [];
/**
* class name
* This should be instance of \Smarty\Security.
*
* @var string
* @see \Smarty\Security
*/
public $security_class = \Smarty\Security::class;
/**
* implementation of security class
*
* @var \Smarty\Security
*/
public $security_policy = null;
/**
* debug mode
* Setting this to true enables the debug-console. Setting it to 2 enables individual Debug Console window by
* template name.
*
* @var boolean|int
*/
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 string
*/
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;
/**
* 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;
/**
* locking concurrent compiles
*
* @var boolean
*/
public $compile_locking = true;
/**
* Controls whether cache resources should use 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;
/**
* resource type used if none given
* Must be a valid key of $registered_resources.
*
* @var string
*/
public $default_resource_type = 'file';
/**
* cache resource
* Must be a subclass of \Smarty\Cacheresource\Base
*
* @var \Smarty\Cacheresource\Base
*/
private $cacheResource;
/**
* config type
*
* @var string
*/
public $default_config_type = 'file';
/**
* check If-Modified-Since headers
*
* @var boolean
*/
public $cache_modified_check = false;
/**
* registered plugins
*
* @var array
*/
public $registered_plugins = [];
/**
* registered objects
*
* @var array
*/
public $registered_objects = [];
/**
* registered classes
*
* @var array
*/
public $registered_classes = [];
/**
* registered resources
*
* @var array
*/
public $registered_resources = [];
/**
* registered cache resources
*
* @var array
* @deprecated since 5.0
*/
private $registered_cache_resources = [];
/**
* default modifier
*
* @var array
*/
public $default_modifiers = [];
/**
* autoescape variable output
*
* @var boolean
*/
public $escape_html = false;
/**
* start time for execution time calculation
*
* @var int
*/
public $start_time = 0;
/**
* internal flag to enable parser debugging
*
* @var bool
*/
public $_parserdebug = false;
/**
* Debug object
*
* @var \Smarty\Debug
*/
public $_debug = null;
/**
* template directory
*
* @var array
*/
protected $template_dir = ['./templates/'];
/**
* flags for normalized template directory entries
*
* @var array
*/
protected $_processedTemplateDir = [];
/**
* config directory
*
* @var array
*/
protected $config_dir = ['./configs/'];
/**
* flags for normalized template directory entries
*
* @var array
*/
protected $_processedConfigDir = [];
/**
* compile directory
*
* @var string
*/
protected $compile_dir = './templates_c/';
/**
* cache directory
*
* @var string
*/
protected $cache_dir = './cache/';
/**
* PHP7 Compatibility mode
*
* @var bool
*/
private $isMutingUndefinedOrNullWarnings = false;
/**
* Cache of loaded resource handlers.
*
* @var array
*/
public $_resource_handlers = [];
/**
* Cache of loaded cacheresource handlers.
*
* @var array
*/
public $_cacheresource_handlers = [];
/**
* List of extensions
*
* @var ExtensionInterface[]
*/
private $extensions = [];
/**
* @var BCPluginsAdapter
*/
private $BCPluginsAdapter;
/**
* Initialize new Smarty object
*/
public function __construct() {
$this->start_time = microtime(true);
// Check if we're running on Windows
\Smarty\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\Smarty::$_CHARSET !== 'UTF-8') {
\Smarty\Smarty::$_UTF8_MODIFIER = '';
}
$this->BCPluginsAdapter = new BCPluginsAdapter($this);
$this->extensions[] = new CoreExtension();
$this->extensions[] = new DefaultExtension();
$this->extensions[] = $this->BCPluginsAdapter;
$this->cacheResource = new File();
}
/**
* Load an additional extension.
*
* @return void
*/
public function addExtension(ExtensionInterface $extension) {
$this->extensions[] = $extension;
}
/**
* Returns all loaded extensions
*
* @return array|ExtensionInterface[]
*/
public function getExtensions(): array {
return $this->extensions;
}
/**
* Replace the entire list extensions, allowing you to determine the exact order of the extensions.
*
* @param ExtensionInterface[] $extensions
*
* @return void
*/
public function setExtensions(array $extensions): void {
$this->extensions = $extensions;
}
/**
* Check if a template resource exists
*
* @param string $resource_name template name
*
* @return bool status
* @throws \Smarty\Exception
*/
public function templateExists($resource_name) {
// create source object
$source = Template\Source::load(null, $this, $resource_name);
return $source->exists;
}
/**
* Loads security class and enables security
*
* @param string|\Smarty\Security $security_class if a string is used, it must be class-name
*
* @return static current Smarty instance for chaining
* @throws \Smarty\Exception
*/
public function enableSecurity($security_class = null) {
\Smarty\Security::enableSecurity($this, $security_class);
return $this;
}
/**
* Disable security
*
* @return static current Smarty instance for chaining
*/
public function disableSecurity() {
$this->security_policy = null;
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
* @param bool $isConfig true for config_dir
*
* @return static current Smarty instance for chaining
*/
public function addTemplateDir($template_dir, $key = null, $isConfig = false) {
if ($isConfig) {
$processed = &$this->_processedConfigDir;
$dir = &$this->config_dir;
$this->_configDirNormalized = false;
} else {
$processed = &$this->_processedTemplateDir;
$dir = &$this->template_dir;
$this->_templateDirNormalized = false;
}
if (is_array($template_dir)) {
foreach ($template_dir as $k => $v) {
if (is_int($k)) {
// indexes are not merged but appended
$dir[] = $v;
} else {
// string indexes are overridden
$dir[$k] = $v;
unset($processed[$key]);
}
}
} else {
if ($key !== null) {
// override directory at specified index
$dir[$key] = $template_dir;
unset($processed[$key]);
} else {
// append new directory
$dir[] = $template_dir;
}
}
return $this;
}
/**
* Get template directories
*
* @param mixed $index index of directory to get, null to get all
* @param bool $isConfig true for config_dir
*
* @return array|string list of template directories, or directory of $index
*/
public function getTemplateDir($index = null, $isConfig = false) {
if ($isConfig) {
$dir = &$this->config_dir;
} else {
$dir = &$this->template_dir;
}
if ($isConfig ? !$this->_configDirNormalized : !$this->_templateDirNormalized) {
$this->_normalizeTemplateConfig($isConfig);
}
if ($index !== null) {
return isset($dir[$index]) ? $dir[$index] : null;
}
return $dir;
}
/**
* Set template directory
*
* @param string|array $template_dir directory(s) of template sources
* @param bool $isConfig true for config_dir
*
* @return static current Smarty instance for chaining
*/
public function setTemplateDir($template_dir, $isConfig = false) {
if ($isConfig) {
$this->config_dir = [];
$this->_processedConfigDir = [];
} else {
$this->template_dir = [];
$this->_processedTemplateDir = [];
}
$this->addTemplateDir($template_dir, null, $isConfig);
return $this;
}
/**
* Adds a template directory before any existing directoires
*
* @param string $new_template_dir directory of template sources
* @param bool $is_config true for config_dir
*
* @return static current Smarty instance for chaining
*/
public function prependTemplateDir($new_template_dir, $is_config = false) {
$current_template_dirs = $is_config ? $this->config_dir : $this->template_dir;
array_unshift($current_template_dirs, $new_template_dir);
$this->setTemplateDir($current_template_dirs, $is_config);
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 static current Smarty instance for chaining
*/
public function addConfigDir($config_dir, $key = null) {
return $this->addTemplateDir($config_dir, $key, true);
}
/**
* Get config directory
*
* @param mixed $index index of directory to get, null to get all
*
* @return array configuration directory
*/
public function getConfigDir($index = null) {
return $this->getTemplateDir($index, true);
}
/**
* Set config directory
*
* @param $config_dir
*
* @return static current Smarty instance for chaining
*/
public function setConfigDir($config_dir) {
return $this->setTemplateDir($config_dir, true);
}
/**
* Registers plugin to be used in templates
*
* @param string $type plugin type
* @param string $name name of template tag
* @param callable $callback PHP callback to register
* @param bool $cacheable if true (default) this function is cache able
*
* @return $this
* @throws \Smarty\Exception
*
* @api Smarty::registerPlugin()
*/
public function registerPlugin($type, $name, $callback, $cacheable = true) {
if (isset($this->registered_plugins[$type][$name])) {
throw new Exception("Plugin tag '{$name}' already registered");
} elseif (!is_callable($callback) && !class_exists($callback)) {
throw new Exception("Plugin '{$name}' not callable");
} else {
$this->registered_plugins[$type][$name] = [$callback, (bool)$cacheable];
}
return $this;
}
/**
* Returns plugin previously registered using ::registerPlugin as a numerical array as follows or null if not found:
* [
* 0 => the callback
* 1 => (bool) $cacheable
* 2 => (array) $cache_attr
* ]
*
* @param string $type plugin type
* @param string $name name of template tag
*
* @return array|null
*
* @api Smarty::unregisterPlugin()
*/
public function getRegisteredPlugin($type, $name): ?array {
if (isset($this->registered_plugins[$type][$name])) {
return $this->registered_plugins[$type][$name];
}
return null;
}
/**
* Unregisters plugin previously registered using ::registerPlugin
*
* @param string $type plugin type
* @param string $name name of template tag
*
* @return $this
*
* @api Smarty::unregisterPlugin()
*/
public function unregisterPlugin($type, $name) {
if (isset($this->registered_plugins[$type][$name])) {
unset($this->registered_plugins[$type][$name]);
}
return $this;
}
/**
* Adds directory of plugin files
*
* @param null|array|string $plugins_dir
*
* @return static current Smarty instance for chaining
* @deprecated since 5.0
*/
public function addPluginsDir($plugins_dir) {
trigger_error('Using Smarty::addPluginsDir() to load plugins is deprecated and will be ' .
'removed in a future release. Use Smarty::addExtension() to add an extension or Smarty::registerPlugin to ' .
'quickly register a plugin using a callback function.', E_USER_DEPRECATED);
foreach ((array)$plugins_dir as $v) {
$path = $this->_realpath(rtrim($v ?? '', '/\\') . DIRECTORY_SEPARATOR, true);
$this->BCPluginsAdapter->loadPluginsFromDir($path);
}
return $this;
}
/**
* Get plugin directories
*
* @return array list of plugin directories
* @deprecated since 5.0
*/
public function getPluginsDir() {
trigger_error('Using Smarty::getPluginsDir() is deprecated and will be ' .
'removed in a future release. It will always return an empty array.', E_USER_DEPRECATED);
return [];
}
/**
* Set plugins directory
*
* @param string|array $plugins_dir directory(s) of plugins
*
* @return static current Smarty instance for chaining
* @deprecated since 5.0
*/
public function setPluginsDir($plugins_dir) {
trigger_error('Using Smarty::getPluginsDir() is deprecated and will be ' .
'removed in a future release. For now, it will remove the DefaultExtension from the extensions list and ' .
'proceed to call Smartyy::addPluginsDir..', E_USER_DEPRECATED);
$this->extensions = array_filter(
$this->extensions,
function ($extension) {
return !($extension instanceof DefaultExtension);
}
);
return $this->addPluginsDir($plugins_dir);
}
/**
* Registers a default plugin handler
*
* @param callable $callback class/method name
*
* @return $this
* @throws Exception if $callback is not callable
*
* @api Smarty::registerDefaultPluginHandler()
*
* @deprecated since 5.0
*/
public function registerDefaultPluginHandler($callback) {
trigger_error('Using Smarty::registerDefaultPluginHandler() is deprecated and will be ' .
'removed in a future release. Please rewrite your plugin handler as an extension.',
E_USER_DEPRECATED);
if (is_callable($callback)) {
$this->default_plugin_handler_func = $callback;
} else {
throw new Exception("Default plugin handler '$callback' not callable");
}
return $this;
}
/**
* Get compiled directory
*
* @return string path to compiled templates
*/
public function getCompileDir() {
if (!$this->_compileDirNormalized) {
$this->_normalizeDir('compile_dir', $this->compile_dir);
$this->_compileDirNormalized = true;
}
return $this->compile_dir;
}
/**
*
* @param string $compile_dir directory to store compiled templates in
*
* @return static current Smarty instance for chaining
*/
public function setCompileDir($compile_dir) {
$this->_normalizeDir('compile_dir', $compile_dir);
$this->_compileDirNormalized = true;
return $this;
}
/**
* Get cache directory
*
* @return string path of cache directory
*/
public function getCacheDir() {
if (!$this->_cacheDirNormalized) {
$this->_normalizeDir('cache_dir', $this->cache_dir);
$this->_cacheDirNormalized = true;
}
return $this->cache_dir;
}
/**
* Set cache directory
*
* @param string $cache_dir directory to store cached templates in
*
* @return static current Smarty instance for chaining
*/
public function setCacheDir($cache_dir) {
$this->_normalizeDir('cache_dir', $cache_dir);
$this->_cacheDirNormalized = true;
return $this;
}
private $templates = [];
/**
* Creates a template object
*
* @param string $template_name
* @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 null $parent next higher level of Smarty variables
*
* @return Template template object
* @throws Exception
*/
public function createTemplate($template_name, $cache_id = null, $compile_id = null, $parent = null): Template {
$data = [];
// Shuffle params for backward compatibility: if 2nd param is an object, it's the parent
if (is_object($cache_id)) {
$parent = $cache_id;
$cache_id = null;
}
// Shuffle params for backward compatibility: if 2nd param is an array, it's data
if (is_array($cache_id)) {
$data = $cache_id;
$cache_id = null;
}
return $this->doCreateTemplate($template_name, $cache_id, $compile_id, $parent, null, null, false, $data);
}
/**
* Get unique template id
*
* @param string $resource_name
* @param null|mixed $cache_id
* @param null|mixed $compile_id
* @param null $caching
*
* @return string
*/
private function generateUniqueTemplateId(
$resource_name,
$cache_id = null,
$compile_id = null,
$caching = null
): string {
// defaults for optional params
$cache_id = $cache_id ?? $this->cache_id;
$compile_id = $compile_id ?? $this->compile_id;
$caching = (int)$caching ?? $this->caching;
// Add default resource type to resource name if it is missing
if (strpos($resource_name, ':') === false) {
$resource_name = "{$this->default_resource_type}:{$resource_name}";
}
$_templateId = $resource_name . '#' . $cache_id . '#' . $compile_id . '#' . $caching;
// hash very long IDs to prevent problems with filename length
// do not hash shorter IDs, so they remain recognizable
if (strlen($_templateId) > 150) {
$_templateId = sha1($_templateId);
}
return $_templateId;
}
/**
* Normalize path
* - remove /./ and /../
* - make it absolute if required
*
* @param string $path file path
* @param bool $realpath if true - convert to absolute
* false - convert to relative
* null - keep as it is but
* remove /./ /../
*
* @return string
*/
public function _realpath($path, $realpath = null) {
$nds = ['/' => '\\', '\\' => '/'];
preg_match(
'%^(?<root>(?:[[:alpha:]]:[\\\\/]|/|[\\\\]{2}[[:alpha:]]+|[[:print:]]{2,}:[/]{2}|[\\\\])?)(?<path>(.*))$%u',
$path,
$parts
);
$path = $parts['path'];
if ($parts['root'] === '\\') {
$parts['root'] = substr(getcwd(), 0, 2) . $parts['root'];
} else {
if ($realpath !== null && !$parts['root']) {
$path = getcwd() . DIRECTORY_SEPARATOR . $path;
}
}
// normalize DIRECTORY_SEPARATOR
$path = str_replace($nds[DIRECTORY_SEPARATOR], DIRECTORY_SEPARATOR, $path);
$parts['root'] = str_replace($nds[DIRECTORY_SEPARATOR], DIRECTORY_SEPARATOR, $parts['root']);
do {
$path = preg_replace(
['#[\\\\/]{2}#', '#[\\\\/][.][\\\\/]#', '#[\\\\/]([^\\\\/.]+)[\\\\/][.][.][\\\\/]#'],
DIRECTORY_SEPARATOR,
$path,
-1,
$count
);
} while ($count > 0);
return $realpath !== false ? $parts['root'] . $path : str_ireplace(getcwd(), '.', $parts['root'] . $path);
}
/**
* @param boolean $use_sub_dirs
*/
public function setUseSubDirs($use_sub_dirs) {
$this->use_sub_dirs = $use_sub_dirs;
}
/**
* @param int $error_reporting
*/
public function setErrorReporting($error_reporting) {
$this->error_reporting = $error_reporting;
}
/**
* @param boolean $escape_html
*/
public function setEscapeHtml($escape_html) {
$this->escape_html = $escape_html;
}
/**
* Return auto_literal flag
*
* @return boolean
*/
public function getAutoLiteral() {
return $this->auto_literal;
}
/**
* Set auto_literal flag
*
* @param boolean $auto_literal
*/
public function setAutoLiteral($auto_literal = true) {
$this->auto_literal = $auto_literal;
}
/**
* @param boolean $force_compile
*/
public function setForceCompile($force_compile) {
$this->force_compile = $force_compile;
}
/**
* @param boolean $merge_compiled_includes
*/
public function setMergeCompiledIncludes($merge_compiled_includes) {
$this->merge_compiled_includes = $merge_compiled_includes;
}
/**
* Get left delimiter
*
* @return string
*/
public function getLeftDelimiter() {
return $this->left_delimiter;
}
/**
* Set left delimiter
*
* @param string $left_delimiter
*/
public function setLeftDelimiter($left_delimiter) {
$this->left_delimiter = $left_delimiter;
}
/**
* Get right delimiter
*
* @return string $right_delimiter
*/
public function getRightDelimiter() {
return $this->right_delimiter;
}
/**
* Set right delimiter
*
* @param string
*/
public function setRightDelimiter($right_delimiter) {
$this->right_delimiter = $right_delimiter;
}
/**
* @param boolean $debugging
*/
public function setDebugging($debugging) {
$this->debugging = $debugging;
}
/**
* @param boolean $config_overwrite
*/
public function setConfigOverwrite($config_overwrite) {
$this->config_overwrite = $config_overwrite;
}
/**
* @param boolean $config_booleanize
*/
public function setConfigBooleanize($config_booleanize) {
$this->config_booleanize = $config_booleanize;
}
/**
* @param boolean $config_read_hidden
*/
public function setConfigReadHidden($config_read_hidden) {
$this->config_read_hidden = $config_read_hidden;
}
/**
* @param boolean $compile_locking
*/
public function setCompileLocking($compile_locking) {
$this->compile_locking = $compile_locking;
}
/**
* @param string $default_resource_type
*/
public function setDefaultResourceType($default_resource_type) {
$this->default_resource_type = $default_resource_type;
}
/**
* Test install
*
* @param null $errors
*/
public function testInstall(&$errors = null) {
\Smarty\TestInstall::testInstall($this, $errors);
}
/**
* Get Smarty object
*
* @return static
*/
public function getSmarty() {
return $this;
}
/**
* Normalize and set directory string
*
* @param string $dirName cache_dir or compile_dir
* @param string $dir filepath of folder
*/
private function _normalizeDir($dirName, $dir) {
$this->{$dirName} = $this->_realpath(rtrim($dir ?? '', "/\\") . DIRECTORY_SEPARATOR, true);
}
/**
* Normalize template_dir or config_dir
*
* @param bool $isConfig true for config_dir
*/
private function _normalizeTemplateConfig($isConfig) {
if ($isConfig) {
$processed = &$this->_processedConfigDir;
$dir = &$this->config_dir;
} else {
$processed = &$this->_processedTemplateDir;
$dir = &$this->template_dir;
}
if (!is_array($dir)) {
$dir = (array)$dir;
}
foreach ($dir as $k => $v) {
if (!isset($processed[$k])) {
$dir[$k] = $this->_realpath(rtrim($v ?? '', "/\\") . DIRECTORY_SEPARATOR, true);
$processed[$k] = true;
}
}
if ($isConfig) {
$this->_configDirNormalized = true;
$this->_joined_config_dir = join('#', $this->config_dir);
} else {
$this->_templateDirNormalized = true;
$this->_joined_template_dir = join('#', $this->template_dir);
}
}
/**
* Mutes errors for "undefined index", "undefined array key" and "trying to read property of null".
*
* @void
*/
public function muteUndefinedOrNullWarnings(): void {
$this->isMutingUndefinedOrNullWarnings = true;
}
/**
* Indicates if Smarty will mute errors for "undefined index", "undefined array key" and "trying to read property of null".
*
* @return bool
*/
public function isMutingUndefinedOrNullWarnings(): bool {
return $this->isMutingUndefinedOrNullWarnings;
}
/**
* 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 int number of cache files deleted
* @throws \Smarty\Exception
*
* @api Smarty::clearCache()
*/
public function clearCache(
$template_name,
$cache_id = null,
$compile_id = null,
$exp_time = null
) {
return $this->getCacheResource()->clear($this, $template_name, $cache_id, $compile_id, $exp_time);
}
/**
* Empty cache folder
*
* @param integer $exp_time expiration time
* @param string $type resource type
*
* @return int number of cache files deleted
*
* @api Smarty::clearAllCache()
*/
public function clearAllCache($exp_time = null) {
return $this->getCacheResource()->clearAll($this, $exp_time);
}
/**
* Delete compiled template file
*
* @param string $resource_name template name
* @param string $compile_id compile id
* @param integer $exp_time expiration time
*
* @return int number of template files deleted
* @throws \Smarty\Exception
*
* @api Smarty::clearCompiledTemplate()
*/
public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null) {
$_compile_dir = $this->getCompileDir();
if ($_compile_dir === '/') { //We should never want to delete this!
return 0;
}
$_compile_id = isset($compile_id) ? preg_replace('![^\w]+!', '_', $compile_id) : null;
$_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
if (isset($resource_name)) {
$_save_stat = $this->caching;
$this->caching = \Smarty\Smarty::CACHING_OFF;
/* @var Template $tpl */
$tpl = $this->doCreateTemplate($resource_name);
$this->caching = $_save_stat;
if (!$tpl->getSource()->handler->recompiled && $tpl->getSource()->exists) {
$_resource_part_1 = basename(str_replace('^', DIRECTORY_SEPARATOR, $tpl->getCompiled()->filepath));
$_resource_part_1_length = strlen($_resource_part_1);
} else {
return 0;
}
$_resource_part_2 = str_replace('.php', '.cache.php', $_resource_part_1);
$_resource_part_2_length = strlen($_resource_part_2);
}
$_dir = $_compile_dir;
if ($this->use_sub_dirs && isset($_compile_id)) {
$_dir .= $_compile_id . $_dir_sep;
}
if (isset($_compile_id)) {
$_compile_id_part = $_compile_dir . $_compile_id . $_dir_sep;
$_compile_id_part_length = strlen($_compile_id_part);
}
$_count = 0;
try {
$_compileDirs = new RecursiveDirectoryIterator($_dir);
} catch (\UnexpectedValueException $e) {
// path not found / not a dir
return 0;
}
$_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($_compile as $_file) {
if (substr(basename($_file->getPathname()), 0, 1) === '.') {
continue;
}
$_filepath = (string)$_file;
if ($_file->isDir()) {
if (!$_compile->isDot()) {
// delete folder if empty
@rmdir($_file->getPathname());
}
} else {
// delete only php files
if (substr($_filepath, -4) !== '.php') {
continue;
}
$unlink = false;
if ((!isset($_compile_id) ||
(isset($_filepath[$_compile_id_part_length]) &&
$a = !strncmp($_filepath, $_compile_id_part, $_compile_id_part_length)))
&& (!isset($resource_name) || (isset($_filepath[$_resource_part_1_length])
&& substr_compare(
$_filepath,
$_resource_part_1,
-$_resource_part_1_length,
$_resource_part_1_length
) === 0) || (isset($_filepath[$_resource_part_2_length])
&& substr_compare(
$_filepath,
$_resource_part_2,
-$_resource_part_2_length,
$_resource_part_2_length
) === 0))
) {
if (isset($exp_time)) {
if (is_file($_filepath) && time() - filemtime($_filepath) >= $exp_time) {
$unlink = true;
}
} else {
$unlink = true;
}
}
if ($unlink && is_file($_filepath) && @unlink($_filepath)) {
$_count++;
if (function_exists('opcache_invalidate')
&& (!function_exists('ini_get') || strlen(ini_get('opcache.restrict_api')) < 1)
) {
opcache_invalidate($_filepath, true);
} elseif (function_exists('apc_delete_file')) {
apc_delete_file($_filepath);
}
}
}
}
return $_count;
}
/**
* 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
* @api Smarty::compileAllTemplates()
*
*/
public function compileAllTemplates(
$extension = '.tpl',
$force_compile = false,
$time_limit = 0,
$max_errors = null
) {
return $this->compileAll($extension, $force_compile, $time_limit, $max_errors);
}
/**
* 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 int number of template files recompiled
* @api Smarty::compileAllConfig()
*
*/
public function compileAllConfig(
$extension = '.conf',
$force_compile = false,
$time_limit = 0,
$max_errors = null
) {
return $this->compileAll($extension, $force_compile, $time_limit, $max_errors, true);
}
/**
* Compile all template or config files
*
* @param string $extension template file name extension
* @param bool $force_compile force all to recompile
* @param int $time_limit set maximum execution time
* @param int $max_errors set maximum allowed errors
* @param bool $isConfig flag true if called for config files
*
* @return int number of template files compiled
*/
protected function compileAll(
$extension,
$force_compile,
$time_limit,
$max_errors,
$isConfig = false
) {
// switch off time limit
if (function_exists('set_time_limit')) {
@set_time_limit($time_limit);
}
$_count = 0;
$_error_count = 0;
$sourceDir = $isConfig ? $this->getConfigDir() : $this->getTemplateDir();
// loop over array of source directories
foreach ($sourceDir as $_dir) {
$_dir_1 = new RecursiveDirectoryIterator(
$_dir,
defined('FilesystemIterator::FOLLOW_SYMLINKS') ?
FilesystemIterator::FOLLOW_SYMLINKS : 0
);
$_dir_2 = new RecursiveIteratorIterator($_dir_1);
foreach ($_dir_2 as $_fileinfo) {
$_file = $_fileinfo->getFilename();
if (substr(basename($_fileinfo->getPathname()), 0, 1) === '.' || strpos($_file, '.svn') !== false) {
continue;
}
if (substr_compare($_file, $extension, -strlen($extension)) !== 0) {
continue;
}
if ($_fileinfo->getPath() !== substr($_dir, 0, -1)) {
$_file = substr($_fileinfo->getPath(), strlen($_dir)) . DIRECTORY_SEPARATOR . $_file;
}
echo "\n", $_dir, '---', $_file;
flush();
$_start_time = microtime(true);
$_smarty = clone $this;
//
$_smarty->force_compile = $force_compile;
try {
$_tpl = $this->doCreateTemplate($_file);
$_tpl->caching = self::CACHING_OFF;
$_tpl->setSource(
$isConfig ? \Smarty\Template\Config::load($_tpl) : \Smarty\Template\Source::load($_tpl)
);
if ($_tpl->mustCompile()) {
$_tpl->compileTemplateSource();
$_count++;
echo ' compiled in ', microtime(true) - $_start_time, ' seconds';
flush();
} else {
echo ' is up to date';
flush();
}
} catch (\Exception $e) {
echo "\n ------>Error: ", $e->getMessage(), "\n";
$_error_count++;
}
// free memory
unset($_tpl);
if ($max_errors !== null && $_error_count === $max_errors) {
echo "\ntoo many errors\n";
exit(1);
}
}
}
echo "\n";
return $_count;
}
/**
* check client side cache
*
* @param \Smarty\Template\Cached $cached
* @param Template $_template
* @param string $content
*
* @throws \Exception
* @throws \Smarty\Exception
*/
public function cacheModifiedCheck(Template\Cached $cached, Template $_template, $content) {
$_isCached = $_template->isCached() && !$_template->getCompiled()->getNocacheCode();
$_last_modified_date =
@substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
if ($_isCached && $cached->timestamp <= strtotime($_last_modified_date)) {
switch (PHP_SAPI) {
case 'cgi': // php-cgi < 5.3
case 'cgi-fcgi': // php-cgi >= 5.3
case 'fpm-fcgi': // php-fpm >= 5.3.3
header('Status: 304 Not Modified');
break;
case 'cli':
if (/* ^phpunit */
!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']) /* phpunit$ */
) {
$_SERVER['SMARTY_PHPUNIT_HEADERS'][] = '304 Not Modified';
}
break;
default:
if (/* ^phpunit */
!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']) /* phpunit$ */
) {
$_SERVER['SMARTY_PHPUNIT_HEADERS'][] = '304 Not Modified';
} else {
header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
}
break;
}
} else {
switch (PHP_SAPI) {
case 'cli':
if (/* ^phpunit */
!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']) /* phpunit$ */
) {
$_SERVER['SMARTY_PHPUNIT_HEADERS'][] =
'Last-Modified: ' . gmdate('D, d M Y H:i:s', $cached->timestamp) . ' GMT';
}
break;
default:
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $cached->timestamp) . ' GMT');
break;
}
echo $content;
}
}
public function getModifierCallback(string $modifierName) {
foreach ($this->getExtensions() as $extension) {
if ($callback = $extension->getModifierCallback($modifierName)) {
return [new CallbackWrapper($modifierName, $callback), 'handle'];
}
}
return null;
}
public function getFunctionHandler(string $functionName): ?\Smarty\FunctionHandler\FunctionHandlerInterface {
foreach ($this->getExtensions() as $extension) {
if ($handler = $extension->getFunctionHandler($functionName)) {
return $handler;
}
}
return null;
}
public function getBlockHandler(string $blockTagName): ?\Smarty\BlockHandler\BlockHandlerInterface {
foreach ($this->getExtensions() as $extension) {
if ($handler = $extension->getBlockHandler($blockTagName)) {
return $handler;
}
}
return null;
}
public function getModifierCompiler(string $modifier): ?\Smarty\Compile\Modifier\ModifierCompilerInterface {
foreach ($this->getExtensions() as $extension) {
if ($handler = $extension->getModifierCompiler($modifier)) {
return $handler;
}
}
return null;
}
/**
* Run pre-filters over template source
*
* @param string $source the content which shall be processed by the filters
* @param Template $template template object
*
* @return string the filtered source
*/
public function runPreFilters($source, Template $template) {
foreach ($this->getExtensions() as $extension) {
/** @var \Smarty\Filter\FilterInterface $filter */
foreach ($extension->getPreFilters() as $filter) {
$source = $filter->filter($source, $template);
}
}
// return filtered output
return $source;
}
/**
* Run post-filters over template's compiled code
*
* @param string $code the content which shall be processed by the filters
* @param Template $template template object
*
* @return string the filtered code
*/
public function runPostFilters($code, Template $template) {
foreach ($this->getExtensions() as $extension) {
/** @var \Smarty\Filter\FilterInterface $filter */
foreach ($extension->getPostFilters() as $filter) {
$code = $filter->filter($code, $template);
}
}
// return filtered output
return $code;
}
/**
* Run filters over template output
*
* @param string $content the content which shall be processed by the filters
* @param Template $template template object
*
* @return string the filtered (modified) output
*/
public function runOutputFilters($content, Template $template) {
foreach ($this->getExtensions() as $extension) {
/** @var \Smarty\Filter\FilterInterface $filter */
foreach ($extension->getOutputFilters() as $filter) {
$content = $filter->filter($content, $template);
}
}
// return filtered output
return $content;
}
/**
* Writes file in a safe way to disk
*
* @param string $_filepath complete filepath
* @param string $_contents file content
*
* @return boolean true
* @throws Exception
*/
public function writeFile($_filepath, $_contents) {
$_error_reporting = error_reporting();
error_reporting($_error_reporting & ~E_NOTICE & ~E_WARNING);
$_dirpath = dirname($_filepath);
// if subdirs, create dir structure
if ($_dirpath !== '.') {
$i = 0;
// loop if concurrency problem occurs
// see https://bugs.php.net/bug.php?id=35326
while (!is_dir($_dirpath)) {
if (@mkdir($_dirpath, 0777, true)) {
break;
}
clearstatcache();
if (++$i === 3) {
error_reporting($_error_reporting);
throw new Exception("unable to create directory {$_dirpath}");
}
sleep(1);
}
}
// write to tmp file, then move to overt file lock race condition
$_tmp_file = $_dirpath . DIRECTORY_SEPARATOR . str_replace(['.', ','], '_', uniqid('wrt', true));
if (!file_put_contents($_tmp_file, $_contents)) {
error_reporting($_error_reporting);
throw new Exception("unable to write file {$_tmp_file}");
}
/*
* Windows' rename() fails if the destination exists,
* Linux' rename() properly handles the overwrite.
* Simply unlink()ing a file might cause other processes
* currently reading that file to fail, but linux' rename()
* seems to be smart enough to handle that for us.
*/
if (\Smarty\Smarty::$_IS_WINDOWS) {
// remove original file
if (is_file($_filepath)) {
@unlink($_filepath);
}
// rename tmp file
$success = @rename($_tmp_file, $_filepath);
} else {
// rename tmp file
$success = @rename($_tmp_file, $_filepath);
if (!$success) {
// remove original file
if (is_file($_filepath)) {
@unlink($_filepath);
}
// rename tmp file
$success = @rename($_tmp_file, $_filepath);
}
}
if (!$success) {
error_reporting($_error_reporting);
throw new Exception("unable to write file {$_filepath}");
}
// set file permissions
@chmod($_filepath, 0666 & ~umask());
error_reporting($_error_reporting);
return true;
}
private $runtimes = [];
/**
* Loads and returns a runtime extension or null if not found
*
* @param string $type
*
* @return object|null
*/
public function getRuntime(string $type) {
if (isset($this->runtimes[$type])) {
return $this->runtimes[$type];
}
// Lazy load runtimes when/if needed
switch ($type) {
case 'Capture':
return $this->runtimes[$type] = new CaptureRuntime();
case 'Foreach':
return $this->runtimes[$type] = new ForeachRuntime();
case 'Inheritance':
return $this->runtimes[$type] = new InheritanceRuntime();
case 'TplFunction':
return $this->runtimes[$type] = new TplFunctionRuntime();
case 'DefaultPluginHandler':
return $this->runtimes[$type] = new DefaultPluginHandlerRuntime(
$this->getDefaultPluginHandlerFunc()
);
}
throw new \Smarty\Exception('Trying to load invalid runtime ' . $type);
}
/**
* Indicates if a runtime is available.
*
* @param string $type
*
* @return bool
*/
public function hasRuntime(string $type): bool {
try {
$this->getRuntime($type);
return true;
} catch (\Smarty\Exception $e) {
return false;
}
}
/**
* @return callable|null
*/
public function getDefaultPluginHandlerFunc(): ?callable {
return $this->default_plugin_handler_func;
}
/**
* load a filter of specified type and name
*
* @param string $type filter type
* @param string $name filter name
*
* @return bool
* @throws \Smarty\Exception
* @api Smarty::loadFilter()
*
* @deprecated since 5.0
*/
public function loadFilter($type, $name) {
if ($type == \Smarty\Smarty::FILTER_VARIABLE) {
foreach ($this->getExtensions() as $extension) {
if ($extension->getModifierCallback($name)) {
trigger_error('Using Smarty::loadFilter() to load variable filters is deprecated and will ' .
'be removed in a future release. Use Smarty::addDefaultModifiers() to add a modifier.',
E_USER_DEPRECATED);
$this->addDefaultModifiers([$name]);
return true;
}
}
}
trigger_error('Using Smarty::loadFilter() to load filters is deprecated and will be ' .
'removed in a future release. Use Smarty::addExtension() to add an extension or Smarty::registerFilter to ' .
'quickly register a filter using a callback function.', E_USER_DEPRECATED);
if ($type == \Smarty\Smarty::FILTER_OUTPUT && $name == 'trimwhitespace') {
$this->BCPluginsAdapter->addOutputFilter(new TrimWhitespace());
return true;
}
$_plugin = "smarty_{$type}filter_{$name}";
if (!is_callable($_plugin) && class_exists($_plugin, false)) {
$_plugin = [$_plugin, 'execute'];
}
if (is_callable($_plugin)) {
$this->registerFilter($type, $_plugin, $name);
return true;
}
throw new Exception("{$type}filter '{$name}' not found or callable");
}
/**
* load a filter of specified type and name
*
* @param string $type filter type
* @param string $name filter name
*
* @return static
* @throws \Smarty\Exception
* @api Smarty::unloadFilter()
*
*
* @deprecated since 5.0
*/
public function unloadFilter($type, $name) {
trigger_error('Using Smarty::unloadFilter() to unload filters is deprecated and will be ' .
'removed in a future release. Use Smarty::addExtension() to add an extension or Smarty::(un)registerFilter to ' .
'quickly (un)register a filter using a callback function.', E_USER_DEPRECATED);
return $this->unregisterFilter($type, $name);
}
private $_caching_type = 'file';
/**
* @param $type
*
* @return void
* @deprecated since 5.0
*/
public function setCachingType($type) {
trigger_error('Using Smarty::setCachingType() is deprecated and will be ' .
'removed in a future release. Use Smarty::setCacheResource() instead.', E_USER_DEPRECATED);
$this->_caching_type = $type;
$this->activateBCCacheResource();
}
/**
* @return string
* @deprecated since 5.0
*/
public function getCachingType(): string {
trigger_error('Using Smarty::getCachingType() is deprecated and will be ' .
'removed in a future release.', E_USER_DEPRECATED);
return $this->_caching_type;
}
/**
* Registers a resource to fetch a template
*
* @param string $name name of resource type
* @param Base $resource_handler
*
* @return static
*
* @api Smarty::registerCacheResource()
*
* @deprecated since 5.0
*/
public function registerCacheResource($name, \Smarty\Cacheresource\Base $resource_handler) {
trigger_error('Using Smarty::registerCacheResource() is deprecated and will be ' .
'removed in a future release. Use Smarty::setCacheResource() instead.', E_USER_DEPRECATED);
$this->registered_cache_resources[$name] = $resource_handler;
$this->activateBCCacheResource();
return $this;
}
/**
* Unregisters a resource to fetch a template
*
* @param $name
*
* @return static
* @api Smarty::unregisterCacheResource()
*
* @deprecated since 5.0
*
*/
public function unregisterCacheResource($name) {
trigger_error('Using Smarty::unregisterCacheResource() is deprecated and will be ' .
'removed in a future release.', E_USER_DEPRECATED);
if (isset($this->registered_cache_resources[$name])) {
unset($this->registered_cache_resources[$name]);
}
return $this;
}
private function activateBCCacheResource() {
if ($this->_caching_type == 'file') {
$this->setCacheResource(new File());
}
if (isset($this->registered_cache_resources[$this->_caching_type])) {
$this->setCacheResource($this->registered_cache_resources[$this->_caching_type]);
}
}
/**
* Registers a filter function
*
* @param string $type filter type
* @param callable $callback
* @param string|null $name optional filter name
*
* @return static
* @throws \Smarty\Exception
*
* @api Smarty::registerFilter()
*/
public function registerFilter($type, $callback, $name = null) {
$name = $name ?? $this->_getFilterName($callback);
if (!is_callable($callback)) {
throw new Exception("{$type}filter '{$name}' not callable");
}
switch ($type) {
case 'variable':
$this->registerPlugin(self::PLUGIN_MODIFIER, $name, $callback);
trigger_error('Using Smarty::registerFilter() to register variable filters is deprecated and ' .
'will be removed in a future release. Use Smarty::addDefaultModifiers() to add a modifier.',
E_USER_DEPRECATED);
$this->addDefaultModifiers([$name]);
break;
case 'output':
$this->BCPluginsAdapter->addCallableAsOutputFilter($callback, $name);
break;
case 'pre':
$this->BCPluginsAdapter->addCallableAsPreFilter($callback, $name);
break;
case 'post':
$this->BCPluginsAdapter->addCallableAsPostFilter($callback, $name);
break;
default:
throw new Exception("Illegal filter type '{$type}'");
}
return $this;
}
/**
* Return internal filter name
*
* @param callback $callable
*
* @return string|null internal filter name or null if callable cannot be serialized
*/
private function _getFilterName($callable) {
if (is_array($callable)) {
$_class_name = is_object($callable[0]) ? get_class($callable[0]) : $callable[0];
return $_class_name . '_' . $callable[1];
} elseif (is_string($callable)) {
return $callable;
}
return null;
}
/**
* Unregisters a filter function. Smarty cannot unregister closures/anonymous functions if
* no name was given in ::registerFilter.
*
* @param string $type filter type
* @param callback|string $name the name previously used in ::registerFilter
*
* @return static
* @throws \Smarty\Exception
* @api Smarty::unregisterFilter()
*
*
*/
public function unregisterFilter($type, $name) {
if (!is_string($name)) {
$name = $this->_getFilterName($name);
}
if ($name) {
switch ($type) {
case 'output':
$this->BCPluginsAdapter->removeOutputFilter($name);
break;
case 'pre':
$this->BCPluginsAdapter->removePreFilter($name);
break;
case 'post':
$this->BCPluginsAdapter->removePostFilter($name);
break;
default:
throw new Exception("Illegal filter type '{$type}'");
}
}
return $this;
}
/**
* Add default modifiers
*
* @param array|string $modifiers modifier or list of modifiers
* to add
*
* @return static
* @api Smarty::addDefaultModifiers()
*
*/
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
* @api Smarty::getDefaultModifiers()
*
*/
public function getDefaultModifiers() {
return $this->default_modifiers;
}
/**
* Set default modifiers
*
* @param array|string $modifiers modifier or list of modifiers
* to set
*
* @return static
* @api Smarty::setDefaultModifiers()
*
*/
public function setDefaultModifiers($modifiers) {
$this->default_modifiers = (array)$modifiers;
return $this;
}
/**
* @return Cacheresource\Base
*/
public function getCacheResource(): Cacheresource\Base {
return $this->cacheResource;
}
/**
* @param Cacheresource\Base $cacheResource
*/
public function setCacheResource(Cacheresource\Base $cacheResource): void {
$this->cacheResource = $cacheResource;
}
/**
* fetches a rendered Smarty template
*
* @param string $template the resource handle of the template file or template object
* @param mixed $cache_id cache id to be used with this template
* @param mixed $compile_id compile id to be used with this template
*
* @return string rendered template output
* @throws Exception
* @throws Exception
*/
public function fetch($template = null, $cache_id = null, $compile_id = null) {
return $this->returnOrCreateTemplate($template, $cache_id, $compile_id)->fetch();
}
/**
* displays a Smarty template
*
* @param string $template the resource handle of the template file or template object
* @param mixed $cache_id cache id to be used with this template
* @param mixed $compile_id compile id to be used with this template
*
* @throws \Exception
* @throws \Smarty\Exception
*/
public function display($template = null, $cache_id = null, $compile_id = null) {
$this->returnOrCreateTemplate($template, $cache_id, $compile_id)->display();
}
/**
* @param $resource_name
* @param $cache_id
* @param $compile_id
* @param $parent
* @param $caching
* @param $cache_lifetime
* @param bool $isConfig
* @param array $data
*
* @return Template
* @throws Exception
*/
public function doCreateTemplate(
$resource_name,
$cache_id = null,
$compile_id = null,
$parent = null,
$caching = null,
$cache_lifetime = null,
bool $isConfig = false,
array $data = []): Template {
if (!$this->_templateDirNormalized) {
$this->_normalizeTemplateConfig(false);
}
$_templateId = $this->generateUniqueTemplateId($resource_name, $cache_id, $compile_id, $caching);
if (!isset($this->templates[$_templateId])) {
$newTemplate = new Template($resource_name, $this, $parent ?: $this, $cache_id, $compile_id, $caching, $isConfig);
$newTemplate->templateId = $_templateId; // @TODO this could go in constructor ^?
$this->templates[$_templateId] = $newTemplate;
}
$tpl = clone $this->templates[$_templateId];
$tpl->setParent($parent ?: $this);
if ($cache_lifetime) {
$tpl->setCacheLifetime($cache_lifetime);
}
// fill data if present
foreach ($data as $_key => $_val) {
$tpl->assign($_key, $_val);
}
$tpl->tplFunctions = array_merge($parent->tplFunctions ?? [], $tpl->tplFunctions ?? []);
if (!$this->debugging && $this->debugging_ctrl === 'URL') {
$tpl->getSmarty()->getDebug()->debugUrl($tpl->getSmarty());
}
return $tpl;
}
/**
* test if cache is valid
*
* @param null|string|Template $template the resource handle of the template file or template
* object
* @param mixed $cache_id cache id to be used with this template
* @param mixed $compile_id compile id to be used with this template
*
* @return bool cache status
* @throws \Exception
* @throws \Smarty\Exception
*
* @api Smarty::isCached()
*/
public function isCached($template = null, $cache_id = null, $compile_id = null) {
return $this->returnOrCreateTemplate($template, $cache_id, $compile_id)->isCached();
}
/**
* @param $template
* @param $cache_id
* @param $compile_id
* @param $parent
*
* @return Template
* @throws Exception
*/
private function returnOrCreateTemplate($template, $cache_id = null, $compile_id = null) {
if (!($template instanceof Template)) {
$template = $this->createTemplate($template, $cache_id, $compile_id, $this);
$template->caching = $this->caching;
}
return $template;
}
/**
* Sets if Smarty should check If-Modified-Since headers to determine cache validity.
* @param bool $cache_modified_check
* @return void
*/
public function setCacheModifiedCheck($cache_modified_check): void {
$this->cache_modified_check = (bool) $cache_modified_check;
}
}