From cfdd53c6b4b830228cbd3d15444ddb272df711d5 Mon Sep 17 00:00:00 2001 From: Uwe Tews Date: Fri, 2 Jan 2015 12:11:21 +0100 Subject: [PATCH] restructure config file processing move code into an extension class use Smarty_Internal_Template --- change_log.txt | 3 +- libs/sysplugins/smarty_config_source.php | 94 ------ .../smarty_internal_compile_config_load.php | 3 +- libs/sysplugins/smarty_internal_config.php | 306 ------------------ .../smarty_internal_config_file_compiler.php | 75 +++-- libs/sysplugins/smarty_internal_data.php | 111 ++----- .../smarty_internal_extension_config.php | 159 +++++++++ libs/sysplugins/smarty_template_config.php | 118 +++++++ 8 files changed, 367 insertions(+), 502 deletions(-) delete mode 100644 libs/sysplugins/smarty_config_source.php delete mode 100644 libs/sysplugins/smarty_internal_config.php create mode 100644 libs/sysplugins/smarty_internal_extension_config.php create mode 100644 libs/sysplugins/smarty_template_config.php diff --git a/change_log.txt b/change_log.txt index 930f0801..c2e1236d 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,7 +1,8 @@  ===== 3.1.22-dev ===== (xx.xx.2015) - optimization restructure template processing by moving code into classes it better belongs to - + - optimization restructure config file processing + 31.12.2014 - bugfix use function_exists('mb_get_info') for setting Smarty::$_MBSTRING. Function mb_split could be overloaded depending on php.ini mbstring.func_overload diff --git a/libs/sysplugins/smarty_config_source.php b/libs/sysplugins/smarty_config_source.php deleted file mode 100644 index fd37e61f..00000000 --- a/libs/sysplugins/smarty_config_source.php +++ /dev/null @@ -1,94 +0,0 @@ -handler = $handler; // Note: prone to circular references - - // Note: these may be ->config_compiler_class etc in the future - //$this->config_compiler_class = $handler->config_compiler_class; - //$this->config_lexer_class = $handler->config_lexer_class; - //$this->config_parser_class = $handler->config_parser_class; - - $this->smarty = $smarty; - $this->resource = $resource; - $this->type = $type; - $this->name = $name; - $this->unique_resource = $unique_resource; - } - - /** - * <> Generic setter. - * - * @param string $property_name valid: content, timestamp, exists - * @param mixed $value newly assigned value (not check for correct type) - * - * @throws SmartyException when the given property name is not valid - */ - public function __set($property_name, $value) - { - switch ($property_name) { - case 'content': - case 'timestamp': - case 'exists': - $this->$property_name = $value; - break; - - default: - throw new SmartyException("invalid config property '$property_name'."); - } - } - - /** - * <> Generic getter. - * - * @param string $property_name valid: content, timestamp, exists - * - * @return mixed|void - * @throws SmartyException when the given property name is not valid - */ - public function __get($property_name) - { - switch ($property_name) { - case 'timestamp': - case 'exists': - $this->handler->populateTimestamp($this); - - return $this->$property_name; - - case 'content': - return $this->content = $this->handler->getContent($this); - - default: - throw new SmartyException("config property '$property_name' does not exist."); - } - } -} diff --git a/libs/sysplugins/smarty_internal_compile_config_load.php b/libs/sysplugins/smarty_internal_compile_config_load.php index 8813664d..5b291bed 100644 --- a/libs/sysplugins/smarty_internal_compile_config_load.php +++ b/libs/sysplugins/smarty_internal_compile_config_load.php @@ -74,8 +74,7 @@ class Smarty_Internal_Compile_Config_Load extends Smarty_Internal_CompileBase } } // create config object - $_output = "smarty, \$_smarty_tpl);"; - $_output .= "\$_config->loadConfigVars($section, '$scope'); ?>"; + $_output = ""; return $_output; } diff --git a/libs/sysplugins/smarty_internal_config.php b/libs/sysplugins/smarty_internal_config.php deleted file mode 100644 index 25694d5a..00000000 --- a/libs/sysplugins/smarty_internal_config.php +++ /dev/null @@ -1,306 +0,0 @@ -data = $data; - $this->smarty = $smarty; - $this->config_resource = $config_resource; - } - - /** - * Returns the compiled filepath - * - * @return string the compiled filepath - */ - public function getCompiledFilepath() - { - return $this->compiled_filepath === null ? - ($this->compiled_filepath = $this->buildCompiledFilepath()) : - $this->compiled_filepath; - } - - /** - * Get file path. - * - * @return string - */ - public function buildCompiledFilepath() - { - $_compile_id = isset($this->smarty->compile_id) ? preg_replace('![^\w\|]+!', '_', $this->smarty->compile_id) : null; - $_flag = (int) $this->smarty->config_read_hidden + (int) $this->smarty->config_booleanize * 2 - + (int) $this->smarty->config_overwrite * 4; - $_filepath = sha1(realpath($this->source->filepath) . $_flag); - // if use_sub_dirs, break file into directories - if ($this->smarty->use_sub_dirs) { - $_filepath = substr($_filepath, 0, 2) . DS - . substr($_filepath, 2, 2) . DS - . substr($_filepath, 4, 2) . DS - . $_filepath; - } - $_compile_dir_sep = $this->smarty->use_sub_dirs ? DS : '^'; - if (isset($_compile_id)) { - $_filepath = $_compile_id . $_compile_dir_sep . $_filepath; - } - $_compile_dir = $this->smarty->getCompileDir(); - - return $_compile_dir . $_filepath . '.' . basename($this->source->name) . '.config' . '.php'; - } - - /** - * Returns the timestamp of the compiled file - * - * @return integer the file timestamp - */ - public function getCompiledTimestamp() - { - return $this->compiled_timestamp === null - ? ($this->compiled_timestamp = (file_exists($this->getCompiledFilepath())) ? filemtime($this->getCompiledFilepath()) : false) - : $this->compiled_timestamp; - } - - /** - * Returns if the current config file must be compiled - * It does compare the timestamps of config source and the compiled config and checks the force compile configuration - * - * @return boolean true if the file must be compiled - */ - public function mustCompile() - { - return $this->mustCompile === null ? - $this->mustCompile = ($this->smarty->force_compile || $this->getCompiledTimestamp() === false || $this->smarty->compile_check && $this->getCompiledTimestamp() < $this->source->timestamp) : - $this->mustCompile; - } - - /** - * Returns the compiled config file - * It checks if the config file must be compiled or just read the compiled version - * - * @return string the compiled config file - */ - public function getCompiledConfig() - { - if ($this->compiled_config === null) { - // see if template needs compiling. - if ($this->mustCompile()) { - $this->compileConfigSource(); - } else { - $this->compiled_config = file_get_contents($this->getCompiledFilepath()); - } - } - - return $this->compiled_config; - } - - /** - * Compiles the config files - * - * @throws Exception - */ - public function compileConfigSource() - { - // compile template - if (!is_object($this->compiler_object)) { - // load compiler - $this->compiler_object = new Smarty_Internal_Config_File_Compiler($this->smarty); - } - // compile locking - if ($this->smarty->compile_locking) { - if ($saved_timestamp = $this->getCompiledTimestamp()) { - touch($this->getCompiledFilepath()); - } - } - // call compiler - try { - $this->compiler_object->compileSource($this); - } - catch (Exception $e) { - // restore old timestamp in case of error - if ($this->smarty->compile_locking && $saved_timestamp) { - touch($this->getCompiledFilepath(), $saved_timestamp); - } - throw $e; - } - // compiling succeeded - // write compiled template - Smarty_Internal_Write_File::writeFile($this->getCompiledFilepath(), $this->getCompiledConfig(), $this->smarty); - } - - /** - * load config variables - * - * @param mixed $sections array of section names, single section or null - * @param string $scope global,parent or local - * - * @throws Exception - */ - public function loadConfigVars($sections = null, $scope = 'local') - { - if ($this->data instanceof Smarty_Internal_Template) { - $this->data->properties['file_dependency'][sha1($this->source->filepath)] = array($this->source->filepath, $this->source->timestamp, 'file'); - } - if ($this->mustCompile()) { - $this->compileConfigSource(); - } - // pointer to scope - if ($scope == 'local') { - $scope_ptr = $this->data; - } elseif ($scope == 'parent') { - if (isset($this->data->parent)) { - $scope_ptr = $this->data->parent; - } else { - $scope_ptr = $this->data; - } - } elseif ($scope == 'root' || $scope == 'global') { - $scope_ptr = $this->data; - while (isset($scope_ptr->parent)) { - $scope_ptr = $scope_ptr->parent; - } - } - $_config_vars = array(); - include($this->getCompiledFilepath()); - // copy global config vars - foreach ($_config_vars['vars'] as $variable => $value) { - if ($this->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) { - $scope_ptr->config_vars[$variable] = $value; - } else { - $scope_ptr->config_vars[$variable] = array_merge((array) $scope_ptr->config_vars[$variable], (array) $value); - } - } - // scan sections - if (!empty($sections)) { - foreach ((array) $sections as $this_section) { - if (isset($_config_vars['sections'][$this_section])) { - foreach ($_config_vars['sections'][$this_section]['vars'] as $variable => $value) { - if ($this->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) { - $scope_ptr->config_vars[$variable] = $value; - } else { - $scope_ptr->config_vars[$variable] = array_merge((array) $scope_ptr->config_vars[$variable], (array) $value); - } - } - } - } - } - } - - /** - * set Smarty property in template context - * - * @param string $property_name property name - * @param mixed $value value - * - * @throws SmartyException if $property_name is not valid - */ - public function __set($property_name, $value) - { - switch ($property_name) { - case 'source': - case 'compiled': - $this->$property_name = $value; - - return; - } - - throw new SmartyException("invalid config property '$property_name'."); - } - - /** - * get Smarty property in template context - * - * @param string $property_name property name - * - * @return \Smarty_Config_Source|\Smarty_Template_Compiled - * @throws SmartyException if $property_name is not valid - */ - public function __get($property_name) - { - switch ($property_name) { - case 'source': - if (empty($this->config_resource)) { - throw new SmartyException("Unable to parse resource name \"{$this->config_resource}\""); - } - $this->source = Smarty_Resource::config($this); - - return $this->source; - - case 'compiled': - $this->compiled = $this->source->getCompiled($this); - - return $this->compiled; - } - - throw new SmartyException("config attribute '$property_name' does not exist."); - } -} diff --git a/libs/sysplugins/smarty_internal_config_file_compiler.php b/libs/sysplugins/smarty_internal_config_file_compiler.php index 11731043..50779c7b 100644 --- a/libs/sysplugins/smarty_internal_config_file_compiler.php +++ b/libs/sysplugins/smarty_internal_config_file_compiler.php @@ -17,6 +17,19 @@ */ class Smarty_Internal_Config_File_Compiler { + /** + * Lexer class name + * + * @var string + */ + public $lexer_class; + + /** + * Parser class name + * + * @var string + */ + public $parser_class; /** * Lexer object * @@ -41,9 +54,9 @@ class Smarty_Internal_Config_File_Compiler /** * Smarty object * - * @var Smarty_Internal_Config object + * @var Smarty_Internal_Template object */ - public $config; + public $template; /** * Compiled config data sections and variables @@ -52,40 +65,52 @@ class Smarty_Internal_Config_File_Compiler */ public $config_data = array(); + /** + * compiled config data must always be written + * + * @var bool + */ + public $write_compiled_code = true; + /** * Initialize compiler * - * @param Smarty $smarty base instance + * @param string $lexer_class class name + * @param string $parser_class class name + * @param Smarty $smarty global instance */ - public function __construct($smarty) + public function __construct($lexer_class, $parser_class, Smarty $smarty) { + $this->smarty = $smarty; + // get required plugins + $this->lexer_class = $lexer_class; + $this->parser_class = $parser_class; $this->smarty = $smarty; $this->config_data['sections'] = array(); $this->config_data['vars'] = array(); } /** - * Method to compile a Smarty template. + * Method to compile Smarty config source. * - * @param Smarty_Internal_Config $config config object + * @param Smarty_Internal_Template $template * - * @return bool true if compiling succeeded, false if it failed + * @return bool true if compiling succeeded, false if it failed */ - public function compileSource(Smarty_Internal_Config $config) + public function compileTemplate(Smarty_Internal_Template $template) { - /* here is where the compiling takes place. Smarty - tags in the templates are replaces with PHP code, - then written to compiled files. */ - $this->config = $config; - // get config file source - $_content = $config->source->content . "\n"; - // on empty template just return - if ($_content == '') { + $this->template = $template; + $this->template->properties['file_dependency'][$this->template->source->uid] = array($this->template->source->name, $this->template->source->timestamp, $this->template->source->type); + // on empty config just return + if ($template->source->content == '') { return true; } + if ($this->smarty->debugging) { + Smarty_Internal_Debug::start_compile($this->template); + } // init the lexer/parser to compile the config file - $lex = new Smarty_Internal_Configfilelexer($_content, $this); - $parser = new Smarty_Internal_Configfileparser($lex, $this); + $lex = new $this->lexer_class(str_replace(array("\r\n", "\r"), "\n", $template->source->content) . "\n", $this); + $parser = new $this->parser_class($lex, $this); if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { $mbEncoding = mb_internal_encoding(); @@ -94,7 +119,6 @@ class Smarty_Internal_Config_File_Compiler $mbEncoding = null; } - if ($this->smarty->_parserdebug) { $parser->PrintTrace(); } @@ -111,8 +135,15 @@ class Smarty_Internal_Config_File_Compiler if ($mbEncoding) { mb_internal_encoding($mbEncoding); } + if ($this->smarty->debugging) { + Smarty_Internal_Debug::end_compile($this->template); + } + // template header code + $template_header = "template->source->filepath . "\" */ ?>\n"; - $config->compiled_config = 'config_data, true) . '; ?>'; + $code = 'config_data, true) . '); ?>'; + return $template_header . Smarty_Internal_Extension_CodeFrame::create($this->template, $code); } /** @@ -129,13 +160,13 @@ class Smarty_Internal_Config_File_Compiler { $this->lex = Smarty_Internal_Configfilelexer::instance(); $this->parser = Smarty_Internal_Configfileparser::instance(); - // get template source line which has error + // get config source line which has error $line = $this->lex->line; if (isset($args)) { // $line--; } $match = preg_split("/\n/", $this->lex->data); - $error_text = "Syntax error in config file '{$this->config->source->filepath}' on line {$line} '{$match[$line - 1]}' "; + $error_text = "Syntax error in config file '{$this->template->source->filepath}' on line {$line} '{$match[$line - 1]}' "; if (isset($args)) { // individual error message $error_text .= $args; diff --git a/libs/sysplugins/smarty_internal_data.php b/libs/sysplugins/smarty_internal_data.php index 9a794281..df40f353 100644 --- a/libs/sysplugins/smarty_internal_data.php +++ b/libs/sysplugins/smarty_internal_data.php @@ -103,7 +103,7 @@ class Smarty_Internal_Data { if ($tpl_var != '') { $this->tpl_vars[$tpl_var] = new Smarty_variable(null, $nocache); - $this->tpl_vars[$tpl_var]->value = & $value; + $this->tpl_vars[$tpl_var]->value = &$value; } return $this; @@ -191,10 +191,10 @@ class Smarty_Internal_Data } if ($merge && is_array($value)) { foreach ($value as $_key => $_val) { - $this->tpl_vars[$tpl_var]->value[$_key] = & $value[$_key]; + $this->tpl_vars[$tpl_var]->value[$_key] = &$value[$_key]; } } else { - $this->tpl_vars[$tpl_var]->value[] = & $value; + $this->tpl_vars[$tpl_var]->value[] = &$value; } } @@ -205,7 +205,7 @@ class Smarty_Internal_Data * Returns a single or all template variables * * @param string $varname variable name or null - * @param object $_ptr optional pointer to data object + * @param object $_ptr optional pointer to data object * @param boolean $search_parents include parent templates? * * @return string variable value or or array of variables @@ -292,9 +292,7 @@ class Smarty_Internal_Data public function configLoad($config_file, $sections = null) { // load Config class - $config = new Smarty_Internal_Config($config_file, $this->smarty, $this); - $config->loadConfigVars($sections); - + Smarty_Internal_Extension_Config::configLoad($this, $config_file, $sections); return $this; } @@ -347,21 +345,32 @@ class Smarty_Internal_Data */ public function getConfigVariable($variable, $error_enable = true) { - $_ptr = $this; - while ($_ptr !== null) { - if (isset($_ptr->config_vars[$variable])) { - // found it, return it - return $_ptr->config_vars[$variable]; - } - // not found, try at parent - $_ptr = $_ptr->parent; - } - if ($this->smarty->error_unassigned && $error_enable) { - // force a notice - $x = $$variable; - } + return Smarty_Internal_Extension_Config::getConfigVariable($this, $variable, $error_enable = true); + } - return null; + /** + * Returns a single or all config variables + * + * @param string $varname variable name or null + * @param bool $search_parents + * + * @return string variable value or or array of variables + */ + public function getConfigVars($varname = null, $search_parents = true) + { + return Smarty_Internal_Extension_Config::getConfigVars($this, $varname, $search_parents); + } + + /** + * Deassigns a single or all config variables + * + * @param string $varname variable name or null + * + * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining + */ + public function clearConfig($varname = null) + { + return Smarty_Internal_Extension_Config::clearConfig($this, $varname); } /** @@ -391,58 +400,6 @@ class Smarty_Internal_Data return null; } } - - /** - * Returns a single or all config variables - * - * @param string $varname variable name or null - * @param bool $search_parents - * - * @return string variable value or or array of variables - */ - public function getConfigVars($varname = null, $search_parents = true) - { - $_ptr = $this; - $var_array = array(); - while ($_ptr !== null) { - if (isset($varname)) { - if (isset($_ptr->config_vars[$varname])) { - return $_ptr->config_vars[$varname]; - } - } else { - $var_array = array_merge($_ptr->config_vars, $var_array); - } - // not found, try at parent - if ($search_parents) { - $_ptr = $_ptr->parent; - } else { - $_ptr = null; - } - } - if (isset($varname)) { - return ''; - } else { - return $var_array; - } - } - - /** - * Deassigns a single or all config variables - * - * @param string $varname variable name or null - * - * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining - */ - public function clearConfig($varname = null) - { - if (isset($varname)) { - unset($this->config_vars[$varname]); - } else { - $this->config_vars = array(); - } - - return $this; - } } /** @@ -477,15 +434,15 @@ class Smarty_Data extends Smarty_Internal_Data /** * create Smarty data object * - * @param Smarty|array $_parent parent template - * @param Smarty|Smarty_Internal_Template $smarty global smarty instance - * @param string $name optional data block name + * @param Smarty|array $_parent parent template + * @param Smarty|Smarty_Internal_Template $smarty global smarty instance + * @param string $name optional data block name * * @throws SmartyException */ public function __construct($_parent = null, $smarty = null, $name = null) { - self::$count++; + self::$count ++; $this->dataObjectName = 'Data_object ' . (isset($name) ? "'{$name}'" : self::$count); $this->smarty = $smarty; if (is_object($_parent)) { diff --git a/libs/sysplugins/smarty_internal_extension_config.php b/libs/sysplugins/smarty_internal_extension_config.php new file mode 100644 index 00000000..827031ea --- /dev/null +++ b/libs/sysplugins/smarty_internal_extension_config.php @@ -0,0 +1,159 @@ +smarty->template_class($config_file, $obj->smarty, $obj); + $confObj->caching = Smarty::CACHING_OFF; + $confObj->source = Smarty_Template_Config::load($confObj); + $confObj->source->config_sections = $sections; + $confObj->source->scope = $scope; + $confObj->compiled = Smarty_Template_Compiled::load($confObj); + if ($confObj->smarty->debugging) { + Smarty_Internal_Debug::start_render($confObj); + } + $confObj->compiled->render($confObj); + if ($confObj->smarty->debugging) { + Smarty_Internal_Debug::end_render($confObj); + } + if ($obj instanceof Smarty_Internal_Template) { + $obj->properties['file_dependency'][$confObj->source->uid] = array($confObj->source->filepath, $confObj->source->timestamp, $confObj->source->type); + } + } + + /** + * load config variables + * + * @param mixed $sections array of section names, single section or null + * @param string $scope global,parent or local + * + * @throws Exception + */ + static function loadConfigVars($_template, $_config_vars) + { + $scope = $_template->source->scope; + // pointer to scope (local scope is parent of template object + $scope_ptr = $_template->parent; + if ($scope == 'parent') { + if (isset($_template->parent->parent)) { + $scope_ptr = $_template->parent->parent; + } + } elseif ($scope == 'root' || $scope == 'global') { + while (isset($scope_ptr->parent)) { + $scope_ptr = $scope_ptr->parent; + } + } + // copy global config vars + foreach ($_config_vars['vars'] as $variable => $value) { + if ($_template->config_overwrite || !isset($scope_ptr->config_vars[$variable])) { + $scope_ptr->config_vars[$variable] = $value; + } else { + $scope_ptr->config_vars[$variable] = array_merge((array) $scope_ptr->config_vars[$variable], (array) $value); + } + } + // scan sections + $sections = $_template->source->config_sections; + if (!empty($sections)) { + foreach ((array) $sections as $_template_section) { + if (isset($_config_vars['sections'][$_template_section])) { + foreach ($_config_vars['sections'][$_template_section]['vars'] as $variable => $value) { + if ($_template->config_overwrite || !isset($scope_ptr->config_vars[$variable])) { + $scope_ptr->config_vars[$variable] = $value; + } else { + $scope_ptr->config_vars[$variable] = array_merge((array) $scope_ptr->config_vars[$variable], (array) $value); + } + } + } + } + } + } + + /** + * Returns a single or all config variables + * + * @param string $varname variable name or null + * @param bool $search_parents + * + * @return string variable value or or array of variables + */ + static function getConfigVars($obj, $varname = null, $search_parents = true) + { + $_ptr = $obj; + $var_array = array(); + while ($_ptr !== null) { + if (isset($varname)) { + if (isset($_ptr->config_vars[$varname])) { + return $_ptr->config_vars[$varname]; + } + } else { + $var_array = array_merge($_ptr->config_vars, $var_array); + } + // not found, try at parent + if ($search_parents) { + $_ptr = $_ptr->parent; + } else { + $_ptr = null; + } + } + if (isset($varname)) { + return ''; + } else { + return $var_array; + } + } + + /** + * gets a config variable + * + * @param string $variable the name of the config variable + * @param bool $error_enable + * + * @return mixed the value of the config variable + */ + static function getConfigVariable($obj, $variable, $error_enable = true) + { + $_ptr = $obj; + while ($_ptr !== null) { + if (isset($_ptr->config_vars[$variable])) { + // found it, return it + return $_ptr->config_vars[$variable]; + } + // not found, try at parent + $_ptr = $_ptr->parent; + } + if ($obj->smarty->error_unassigned && $error_enable) { + // force a notice + $x = $$variable; + } + + return null; + } + + /** + * remove a single or all config variables + * + * @param string $name variable name or null + * + * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining + */ + static function clearConfig($obj, $name = null) + { + if (isset($name)) { + unset($obj->config_vars[$name]); + } else { + $obj->config_vars = array(); + } + return $obj; + } +} diff --git a/libs/sysplugins/smarty_template_config.php b/libs/sysplugins/smarty_template_config.php new file mode 100644 index 00000000..22a3b0f5 --- /dev/null +++ b/libs/sysplugins/smarty_template_config.php @@ -0,0 +1,118 @@ +handler = clone $handler; // Note: prone to circular references + $this->resource = $resource; + $this->type = $type; + $this->name = $name; + $this->smarty = $smarty; + } + + /** + * initialize Source Object for given resource + * Either [$_template] or [$smarty, $template_resource] must be specified + * + * @param Smarty_Internal_Template $_template template object + * @param Smarty $smarty smarty object + * @param string $template_resource resource identifier + * + * @return Smarty_Template_Source Source Object + * @throws SmartyException + */ + public static function load(Smarty_Internal_Template $_template = null, Smarty $smarty = null, $template_resource = null) + { + static $_incompatible_resources = array('extends' => true, 'php' => true); + $smarty = $_template->smarty; + $template_resource = $_template->template_resource; + if (empty($template_resource)) { + throw new SmartyException('Missing config name'); + } + // parse resource_name, load resource handler + Smarty_Resource::parseResourceName($template_resource, $smarty->default_config_type, $name, $type); + // make sure configs are not loaded via anything smarty can't handle + if (isset($_incompatible_resources[$type])) { + throw new SmartyException ("Unable to use resource '{$type}' for config"); + } + $resource = Smarty_Resource::load($smarty, $type); + $source = new Smarty_Template_Config($resource, $smarty, $template_resource, $type, $name); + $resource->populate($source, $_template); + if ((!isset($source->exists) || !$source->exists) && isset($_template->smarty->default_config_handler_func)) { + Smarty_Internal_Extension_DefaultTemplateHandler::_getDefault($_template, $source, $resource); + } + $source->unique_resource = $resource->buildUniqueResourceName($smarty, $name, true); + return $source; + } +}