/** * get default content from template or config resource handler * * @param Smarty_Template_Source $source * * @throws \SmartyException */ public static function _getDefaultTemplate(Smarty_Template_Source $source) { if ($source->isConfig) { $default_handler = $source->smarty->default_config_handler_func; } else { $default_handler = $source->smarty->default_template_handler_func; } $_content = $_timestamp = null; $_return = call_user_func_array($default_handler, array($source->type, $source->name, &$_content, &$_timestamp, $source->smarty)); if (is_string($_return)) { $source->exists = is_file($_return); if ($source->exists) { $source->timestamp = filemtime($_return); } else { throw new SmartyException("Default handler: Unable to load " . ($source->isConfig ? 'config' : 'template') . " default file '{$_return}' for '{$source->type}:{$source->name}'"); } $source->name = $source->filepath = $_return; $source->uid = sha1($source->filepath); } elseif ($_return === true) { $source->content = $_content; $source->exists = true; $source->uid = $source->name = sha1($_content); $source->handler = Smarty_Resource::load($source->smarty, 'eval'); } else { $source->exists = false; throw new SmartyException('Default handler: No ' . ($source->isConfig ? 'config' : 'template') . " default content for '{$source->type}:{$source->name}'"); } }
/** * This function is executed automatically when a compiled or cached template file is included * - Decode saved properties from compiled template and cache files * - Check if compiled or cache file is valid * * @param array $properties special template properties * @param bool $cache flag if called from cache file * * @return bool flag if compiled or cache file is valid */ public function decodeProperties(Smarty_Internal_Template $tpl, $properties, $cache = false) { $is_valid = true; if (Smarty::SMARTY_VERSION != $properties['version']) { // new version must rebuild $is_valid = false; } elseif ($is_valid && !empty($properties['file_dependency']) && (!$cache && $tpl->smarty->compile_check || $tpl->smarty->compile_check == 1)) { // check file dependencies at compiled code foreach ($properties['file_dependency'] as $_file_to_check) { if ($_file_to_check[2] == 'file' || $_file_to_check[2] == 'extends' || $_file_to_check[2] == 'php') { if ($tpl->source->filepath == $_file_to_check[0]) { // do not recheck current template continue; //$mtime = $tpl->source->getTimeStamp(); } else { // file and php types can be checked without loading the respective resource handlers $mtime = is_file($_file_to_check[0]) ? filemtime($_file_to_check[0]) : false; } } elseif ($_file_to_check[2] == 'string') { continue; } else { $handler = Smarty_Resource::load($tpl->smarty, $_file_to_check[2]); if ($handler->checkTimestamps()) { $source = Smarty_Template_Source::load($tpl, $tpl->smarty, $_file_to_check[0]); $mtime = $source->getTimeStamp(); } else { continue; } } if (!$mtime || $mtime > $_file_to_check[1]) { $is_valid = false; break; } } } if ($cache) { // CACHING_LIFETIME_SAVED cache expiry has to be validated here since otherwise we'd define the unifunc if ($tpl->caching === Smarty::CACHING_LIFETIME_SAVED && $properties['cache_lifetime'] >= 0 && time() > $tpl->cached->timestamp + $properties['cache_lifetime']) { $is_valid = false; } $tpl->cached->cache_lifetime = $properties['cache_lifetime']; $tpl->cached->valid = $is_valid; $resource = $tpl->cached; } else { $tpl->mustCompile = !$is_valid; $resource = $tpl->compiled; $resource->includes = isset($properties['includes']) ? $properties['includes'] : array(); } if ($is_valid) { $resource->unifunc = $properties['unifunc']; $resource->has_nocache_code = $properties['has_nocache_code']; // $tpl->compiled->nocache_hash = $properties['nocache_hash']; $resource->file_dependency = $properties['file_dependency']; if (isset($properties['tpl_function'])) { $tpl->tpl_function = $properties['tpl_function']; } } return $is_valid && !function_exists($properties['unifunc']); }
/** * 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_Config 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); $template_resource = $_template->template_resource; if (empty($template_resource)) { throw new SmartyException('Missing config name'); } // parse resource_name, load resource handler list($name, $type) = Smarty_Resource::parseResourceName($template_resource, $_template->smarty->default_config_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($_template->smarty, $type); $source = new Smarty_Template_Config($resource, $_template->smarty, $template_resource, $type, $name); $resource->populate($source, $_template); if (!$source->exists && isset($_template->smarty->default_config_handler_func)) { Smarty_Internal_Method_RegisterDefaultTemplateHandler::_getDefaultTemplate($source); } return $source; }
/** * Set source object of inline template by $uid * * @param \Smarty_Internal_Template $tpl * @param string $uid * * @throws \SmartyException */ public function setSource(Smarty_Internal_Template $tpl, $uid = null) { // $uid is set if template is inline if (isset($uid)) { // inline templates have same compiled resource $tpl->compiled = $tpl->parent->compiled; if (isset($tpl->compiled->file_dependency[$uid])) { list($filepath, $timestamp, $resource) = $tpl->compiled->file_dependency[$uid]; $tpl->source = new Smarty_Template_Source(isset($tpl->smarty->_cache['resource_handlers'][$resource]) ? $tpl->smarty->_cache['resource_handlers'][$resource] : Smarty_Resource::load($tpl->smarty, $resource), $tpl->smarty, $filepath, $resource, $filepath); $tpl->source->filepath = $filepath; $tpl->source->timestamp = $timestamp; $tpl->source->exists = true; $tpl->source->uid = $uid; } else { $tpl->source = null; } } else { $tpl->source = null; unset($tpl->compiled); } if (!isset($tpl->source)) { $tpl->source = Smarty_Template_Source::load($tpl); } }
/** * Runtime function to render subtemplate * * @param \Smarty_Internal_Template $parent * @param string $template template name * @param mixed $cache_id cache id * @param mixed $compile_id compile id * @param integer $caching cache mode * @param integer $cache_lifetime life time of cache data * @param array $data passed parameter template variables * @param int $scope scope in which {include_test} should execute * @param bool $forceTplCache cache template object * @param string $uid file dependency uid * @param string $content_func function name * */ public function render(Smarty_Internal_Template $parent, $template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $scope, $forceTplCache, $uid = null, $content_func = null) { // if there are cached template objects calculate $templateID $_templateId = !empty($this->tplObjects) ? $parent->smarty->_getTemplateId($template, $cache_id, $compile_id, $caching) : null; // already in template cache? /* @var Smarty_Internal_Template $tpl */ if (isset($_templateId) && isset($this->tplObjects[$_templateId])) { // clone cached template object because of possible recursive call $tpl = clone $this->tplObjects[$_templateId]; $tpl->parent = $parent; // if $caching mode changed the compiled resource is invalid if ((bool) $tpl->caching !== (bool) $caching) { unset($tpl->compiled); } // get variables from calling scope $tpl->tpl_vars = $parent->tpl_vars; $tpl->config_vars = $parent->config_vars; // get template functions $tpl->tpl_function = $parent->tpl_function; // copy inheritance object? if (isset($parent->ext->_inheritance)) { $tpl->ext->_inheritance = $parent->ext->_inheritance; } else { unset($tpl->ext->_inheritance); } } else { $tpl = clone $parent; $tpl->parent = $parent; if (!isset($tpl->templateId) || $tpl->templateId !== $_templateId) { $tpl->templateId = $_templateId; $tpl->template_resource = $template; $tpl->cache_id = $cache_id; $tpl->compile_id = $compile_id; if (isset($uid)) { // for inline templates we can get all resource information from file dependency if (isset($tpl->compiled->file_dependency[$uid])) { list($filepath, $timestamp, $resource) = $tpl->compiled->file_dependency[$uid]; $tpl->source = new Smarty_Template_Source(isset($tpl->smarty->_cache['resource_handlers'][$resource]) ? $tpl->smarty->_cache['resource_handlers'][$resource] : Smarty_Resource::load($tpl->smarty, $resource), $tpl->smarty, $filepath, $resource, $filepath); $tpl->source->filepath = $filepath; $tpl->source->timestamp = $timestamp; $tpl->source->exists = true; $tpl->source->uid = $uid; } else { $tpl->source = null; } } else { $tpl->source = null; } if (!isset($tpl->source)) { $tpl->source = Smarty_Template_Source::load($tpl); unset($tpl->compiled); } unset($tpl->cached); } } $tpl->caching = $caching; $tpl->cache_lifetime = $cache_lifetime; if ($caching == 9999) { $tpl->cached = $parent->cached; } // set template scope $tpl->scope = $scope; $scopePtr = false; if ($scope & ~Smarty::SCOPE_BUBBLE_UP) { if ($scope == Smarty::SCOPE_GLOBAL) { $tpl->tpl_vars = Smarty::$global_tpl_vars; $tpl->config_vars = $tpl->smarty->config_vars; $scopePtr = true; } else { if ($scope == Smarty::SCOPE_PARENT) { $scopePtr = $parent; } elseif ($scope == Smarty::SCOPE_SMARTY) { $scopePtr = $tpl->smarty; } else { $scopePtr = $tpl; while (isset($scopePtr->parent)) { if ($scopePtr->parent->_objType != 2 && $scope & Smarty::SCOPE_TPL_ROOT) { break; } $scopePtr = $scopePtr->parent; } } $tpl->tpl_vars = $scopePtr->tpl_vars; $tpl->config_vars = $scopePtr->config_vars; } } if (!isset($this->tplObjects[$tpl->_getTemplateId()]) && !$tpl->source->handler->recompiled) { // if template is called multiple times set flag to to cache template objects $forceTplCache = $forceTplCache || isset($this->subTplInfo[$tpl->template_resource]) && $this->subTplInfo[$tpl->template_resource] > 1; // check if template object should be cached if ($tpl->parent->_objType == 2 && isset($this->tplObjects[$tpl->parent->templateId]) || $forceTplCache && $tpl->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_AUTOMATIC || $tpl->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON) { $this->tplObjects[$tpl->_getTemplateId()] = $tpl; } } if (!empty($data)) { // set up variable values foreach ($data as $_key => $_val) { $tpl->tpl_vars[$_key] = new Smarty_Variable($_val); } } if (isset($uid)) { if ($parent->smarty->debugging) { $parent->smarty->_debug->start_template($tpl); $parent->smarty->_debug->start_render($tpl); } $tpl->compiled->getRenderedTemplateCode($tpl, $content_func); if ($parent->smarty->debugging) { $parent->smarty->_debug->end_template($tpl); $parent->smarty->_debug->end_render($tpl); } if ($tpl->caching == 9999 && $tpl->compiled->has_nocache_code) { $parent->cached->hashes[$tpl->compiled->nocache_hash] = true; } } else { if (isset($tpl->compiled)) { $tpl->compiled->render($tpl); } else { $tpl->render(); } } if ($scopePtr) { if ($scope == Smarty::SCOPE_GLOBAL) { Smarty::$global_tpl_vars = $tpl->tpl_vars; $tpl->smarty->config_vars = $tpl->config_vars; } else { $scopePtr->tpl_vars = $tpl->tpl_vars; $scopePtr->config_vars = $tpl->config_vars; } } }
/** * 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) { if ($_template) { $smarty = $_template->smarty; $template_resource = $_template->template_resource; } if (empty($template_resource)) { throw new SmartyException('Missing template name'); } // parse resource_name, load resource handler, identify unique resource name list($name, $type) = Smarty_Resource::parseResourceName($template_resource, $smarty->default_resource_type); $resource = Smarty_Resource::load($smarty, $type); // if resource is not recompiling and resource name is not dotted we can check the source cache if ($smarty->resource_caching && !$resource->recompiled && !(isset($name[1]) && $name[0] == '.' && ($name[1] == '.' || $name[1] == '/'))) { $unique_resource = $resource->buildUniqueResourceName($smarty, $name); if (isset($smarty->source_objects[$unique_resource])) { return $smarty->source_objects[$unique_resource]; } } else { $unique_resource = null; } // create new source object $source = new Smarty_Template_Source($resource, $smarty, $template_resource, $type, $name); $resource->populate($source, $_template); if ((!isset($source->exists) || !$source->exists) && isset($_template->smarty->default_template_handler_func)) { Smarty_Internal_Extension_DefaultTemplateHandler::_getDefault($_template, $source, $resObj); } // on recompiling resources we are done if ($smarty->resource_caching && !$resource->recompiled) { // may by we have already $unique_resource $is_relative = false; if (!isset($unique_resource)) { $is_relative = isset($name[1]) && $name[0] == '.' && ($name[1] == '.' || $name[1] == '/') && ($type == 'file' || isset($_template->parent->source) && $_template->parent->source->type == 'extends'); $unique_resource = $resource->buildUniqueResourceName($smarty, $is_relative ? $source->filepath . $name : $name); } $source->unique_resource = $unique_resource; // save in runtime cache if not relative if (!$is_relative) { $smarty->source_objects[$unique_resource] = $source; } } return $source; }
/** * initialize Config Source Object for given resource * * @param Smarty_Internal_Config $_config config object * @return Smarty_Config_Source Source Object */ public static function config(Smarty_Internal_Config $_config) { static $_incompatible_resources = array('eval' => true, 'string' => true, 'extends' => true, 'php' => true); $config_resource = $_config->config_resource; $smarty = $_config->smarty; if (($pos = strpos($config_resource, ':')) === false) { // no resource given, use default $resource_type = $smarty->default_config_type; $resource_name = $config_resource; } else { // get type and name from path $resource_type = substr($config_resource, 0, $pos); $resource_name = substr($config_resource, $pos + 1); if (strlen($resource_type) == 1) { // 1 char is not resource type, but part of filepath $resource_type = 'file'; $resource_name = $config_resource; } } if (isset($_incompatible_resources[$resource_type])) { throw new SmartyException("Unable to use resource '{$resource_type}' for config"); } $resource = Smarty_Resource::load($smarty, $resource_type); $source = new Smarty_Config_Source($resource, $smarty, $config_resource, $resource_type, $resource_name); $resource->populate($source, null); return $source; }
/** * Compiles code for the {include} tag * * @param array $args array with attributes from parser * @param Smarty_Internal_SmartyTemplateCompiler $compiler compiler object * @param array $parameter array with compilation parameter * * @throws SmartyCompilerException * @return string compiled code */ public function compile($args, Smarty_Internal_SmartyTemplateCompiler $compiler, $parameter) { // check and get attributes $_attr = $this->getAttributes($compiler, $args); $hashResourceName = $fullResourceName = $source_resource = $_attr['file']; $variable_template = false; $cache_tpl = false; // parse resource_name if (preg_match('/^([\'"])(([A-Za-z0-9_\\-]{2,})[:])?(([^$()]+)|(.+))\\1$/', $source_resource, $match)) { $type = !empty($match[3]) ? $match[3] : $compiler->template->smarty->default_resource_type; $name = !empty($match[5]) ? $match[5] : $match[6]; $handler = Smarty_Resource::load($compiler->smarty, $type); if ($handler->recompiled || $handler->uncompiled) { $variable_template = true; } if (!$variable_template) { if ($type != 'string') { $fullResourceName = "{$type}:{$name}"; $compiled = $compiler->parent_compiler->template->compiled; if (isset($compiled->includes[$fullResourceName])) { $compiled->includes[$fullResourceName]++; $cache_tpl = true; } else { $compiled->includes[$fullResourceName] = 1; } $fullResourceName = "'{$fullResourceName}'"; } } if (empty($match[5])) { $variable_template = true; } } else { $variable_template = true; } if ($compiler->inheritanceForceChild) { $hashResourceName .= '-child'; } if (isset($_attr['assign'])) { // output will be stored in a smarty variable instead of being displayed $_assign = $_attr['assign']; } $_parent_scope = Smarty::SCOPE_LOCAL; if (isset($_attr['scope'])) { $_attr['scope'] = trim($_attr['scope'], "'\""); if ($_attr['scope'] == 'parent') { $_parent_scope = Smarty::SCOPE_PARENT; } elseif ($_attr['scope'] == 'root') { $_parent_scope = Smarty::SCOPE_ROOT; } elseif ($_attr['scope'] == 'global') { $_parent_scope = Smarty::SCOPE_GLOBAL; } } // if ($cache_tpl || $variable_template || $compiler->loopNesting > 0) { $_cache_tpl = 'true'; } else { $_cache_tpl = 'false'; } // assume caching is off $_caching = Smarty::CACHING_OFF; if ($_attr['nocache'] === true) { $compiler->tag_nocache = true; } $call_nocache = $compiler->tag_nocache || $compiler->nocache; // caching was on and {include} is not in nocache mode if ($compiler->template->caching && !$compiler->nocache && !$compiler->tag_nocache) { $_caching = self::CACHING_NOCACHE_CODE; } // flag if included template code should be merged into caller $merge_compiled_includes = ($compiler->smarty->merge_compiled_includes || $_attr['inline'] === true) && !$compiler->template->source->handler->recompiled; if ($merge_compiled_includes && $_attr['inline'] !== true) { // variable template name ? if ($variable_template) { $merge_compiled_includes = false; if ($compiler->template->caching) { // must use individual cache file //$_attr['caching'] = 1; } } // variable compile_id? if (isset($_attr['compile_id'])) { if (!(substr_count($_attr['compile_id'], '"') == 2 || substr_count($_attr['compile_id'], "'") == 2 || is_numeric($_attr['compile_id'])) || substr_count($_attr['compile_id'], '(') != 0 || substr_count($_attr['compile_id'], '$_smarty_tpl->') != 0) { $merge_compiled_includes = false; if ($compiler->template->caching) { // must use individual cache file //$_attr['caching'] = 1; } } } } /* * if the {include} tag provides individual parameter for caching or compile_id * the subtemplate must not be included into the common cache file and is treated like * a call in nocache mode. * */ if ($_attr['nocache'] !== true && $_attr['caching']) { $_caching = $_new_caching = (int) $_attr['caching']; $call_nocache = true; } else { $_new_caching = Smarty::CACHING_LIFETIME_CURRENT; } if (isset($_attr['cache_lifetime'])) { $_cache_lifetime = $_attr['cache_lifetime']; $call_nocache = true; $_caching = $_new_caching; } else { $_cache_lifetime = '$_smarty_tpl->cache_lifetime'; } if (isset($_attr['cache_id'])) { $_cache_id = $_attr['cache_id']; $call_nocache = true; $_caching = $_new_caching; } else { $_cache_id = '$_smarty_tpl->cache_id'; } if (isset($_attr['compile_id'])) { $_compile_id = $_attr['compile_id']; } else { $_compile_id = '$_smarty_tpl->compile_id'; } // if subtemplate will be called in nocache mode do not merge if ($compiler->template->caching && $call_nocache) { $merge_compiled_includes = false; } $has_compiled_template = false; if ($merge_compiled_includes) { $c_id = isset($_attr['compile_id']) ? $_attr['compile_id'] : $compiler->template->compile_id; // we must observe different compile_id and caching $t_hash = sha1($c_id . ($_caching ? '--caching' : '--nocaching')); if (!isset($compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash])) { $has_compiled_template = $this->compileInlineTemplate($compiler, $fullResourceName, $_caching, $hashResourceName, $t_hash, $c_id); } else { $has_compiled_template = true; } } // delete {include} standard attributes unset($_attr['file'], $_attr['assign'], $_attr['cache_id'], $_attr['compile_id'], $_attr['cache_lifetime'], $_attr['nocache'], $_attr['caching'], $_attr['scope'], $_attr['inline']); // remaining attributes must be assigned as smarty variable $_vars_nc = ''; if (!empty($_attr)) { if ($_parent_scope == Smarty::SCOPE_LOCAL) { $_pairs = array(); // create variables foreach ($_attr as $key => $value) { $_pairs[] = "'{$key}'=>{$value}"; $_vars_nc .= "\$_smarty_tpl->tpl_vars['{$key}'] = new Smarty_Variable({$value});\n"; } $_vars = 'array(' . join(',', $_pairs) . ')'; } else { $compiler->trigger_template_error('variable passing not allowed in parent/global scope', null, true); } } else { $_vars = 'array()'; } $update_compile_id = $compiler->template->caching && !$compiler->tag_nocache && !$compiler->nocache && $_compile_id != '$_smarty_tpl->compile_id'; if ($has_compiled_template && !$call_nocache) { $_output = "<?php\n"; if ($update_compile_id) { $_output .= $compiler->makeNocacheCode("\$_compile_id_save[] = \$_smarty_tpl->compile_id;\n\$_smarty_tpl->compile_id = {$_compile_id};\n"); } if (!empty($_vars_nc) && $_caching == 9999 && $compiler->template->caching) { //$compiler->suppressNocacheProcessing = false; $_output .= substr($compiler->processNocacheCode('<?php ' . $_vars_nc . "?>\n", true), 6, -3); //$compiler->suppressNocacheProcessing = true; } if (isset($_assign)) { $_output .= "ob_start();\n"; } $_output .= "\$_smarty_tpl->renderInline(\$_smarty_tpl->setupSubTemplate({$fullResourceName}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, {$_cache_tpl}, '{$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['uid']}'), '{$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['func']}');\n"; if (isset($_assign)) { $_output .= "\$_smarty_tpl->tpl_vars[{$_assign}] = new Smarty_Variable(ob_get_clean());\n"; } if ($update_compile_id) { $_output .= $compiler->makeNocacheCode("\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n"); } $_output .= "?>\n"; return $_output; } if ($call_nocache) { $compiler->tag_nocache = true; } $_output = "<?php "; if ($update_compile_id) { $_output .= "\$_compile_id_save[] = \$_smarty_tpl->compile_id;\n\$_smarty_tpl->compile_id = {$_compile_id};\n"; } // was there an assign attribute if (isset($_assign)) { $_output .= "ob_start();\n"; } $_output .= "\$_smarty_tpl->setupSubTemplate({$fullResourceName}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, {$_cache_tpl})->render();\n"; if (isset($_assign)) { $_output .= "\$_smarty_tpl->tpl_vars[{$_assign}] = new Smarty_Variable(ob_get_clean());\n"; } if ($update_compile_id) { $_output .= "\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n"; } $_output .= "?>\n"; return $_output; }
/** * Template code runtime function to set up an inline subtemplate * * @param string $template template name * @param mixed $cache_id cache id * @param mixed $compile_id compile id * @param integer $caching cache mode * @param integer $cache_lifetime life time of cache data * @param array $data passed parameter template variables * @param int $parent_scope scope in which {include} should execute * @param bool $cache_tpl_obj cache template object * @param string|null $uid source uid * * @return \Smarty_Internal_Template template object * @throws \SmartyException */ public function setupSubtemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $cache_tpl_obj, $uid = null) { // if there are cached template objects calculate $templateID $_templateId = isset($this->smarty->_cache['template_objects']) ? $this->smarty->_getTemplateId($template, $cache_id, $compile_id) : null; // already in template cache? /* @var Smarty_Internal_Template $tpl */ if (isset($this->smarty->_cache['template_objects'][$_templateId])) { // clone cached template object because of possible recursive call $tpl = clone $this->smarty->_cache['template_objects'][$_templateId]; $tpl->parent = $this; // if $caching mode changed the compiled resource is invalid if ((bool) $tpl->caching !== (bool) $caching) { unset($tpl->compiled); } // get variables from calling scope if ($parent_scope == Smarty::SCOPE_LOCAL) { $tpl->tpl_vars = $this->tpl_vars; $tpl->config_vars = $this->config_vars; } $tpl->tpl_function = $this->tpl_function; // copy inheritance object? if (isset($this->_inheritance)) { $tpl->_inheritance = $this->_inheritance; } else { unset($tpl->_inheritance); } } else { $tpl = clone $this; $tpl->parent = $this; if (!isset($tpl->templateId) || $tpl->templateId !== $_templateId) { $tpl->templateId = $_templateId; $tpl->template_resource = $template; $tpl->cache_id = $cache_id; $tpl->compile_id = $compile_id; // $uid is set if template is inline if (isset($uid)) { // inline templates have same compiled resource $tpl->compiled = $this->compiled; // if template is called multiple times set flag to to cache template objects if (isset($tpl->compiled->includes[$template]) && $tpl->compiled->includes[$template] > 1) { $cache_tpl_obj = true; } if (isset($tpl->compiled->file_dependency[$uid])) { list($filepath, $timestamp, $resource) = $tpl->compiled->file_dependency[$uid]; $tpl->source = new Smarty_Template_Source(isset($tpl->smarty->_cache['resource_handlers'][$resource]) ? $tpl->smarty->_cache['resource_handlers'][$resource] : Smarty_Resource::load($tpl->smarty, $resource), $tpl->smarty, $filepath, $resource, $filepath); $tpl->source->filepath = $filepath; $tpl->source->timestamp = $timestamp; $tpl->source->exist = true; $tpl->source->uid = $uid; } else { $tpl->source = null; } } else { $tpl->source = null; unset($tpl->compiled); } if (!isset($tpl->source)) { $tpl->source = Smarty_Template_Source::load($tpl); } unset($tpl->cached); // check if template object should be cached if (!$tpl->source->handler->recompiled && (isset($tpl->parent->templateId) && isset($tpl->smarty->_cache['template_objects'][$tpl->parent->templateId]) || $cache_tpl_obj && $tpl->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_AUTOMATIC || $tpl->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON)) { $tpl->smarty->_cache['template_objects'][$tpl->_getTemplateId()] = $tpl; } } } $tpl->caching = $caching; $tpl->cache_lifetime = $cache_lifetime; if ($caching == 9999) { $tpl->cached = $this->cached; } // get variables from calling scope if ($parent_scope != Smarty::SCOPE_LOCAL) { if ($parent_scope == Smarty::SCOPE_PARENT) { $tpl->tpl_vars =& $this->tpl_vars; $tpl->config_vars =& $this->config_vars; } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) { $tpl->tpl_vars =& Smarty::$global_tpl_vars; $tpl->config_vars = $this->config_vars; } elseif ($parent_scope == Smarty::SCOPE_ROOT) { $ptr = $tpl->parent; while (!empty($ptr->parent)) { $ptr = $ptr->parent; } $tpl->tpl_vars =& $ptr->tpl_vars; $tpl->config_vars =& $ptr->config_vars; } else { $tpl->tpl_vars = $this->tpl_vars; $tpl->config_vars = $this->config_vars; } } if (!empty($data)) { // set up variable values foreach ($data as $_key => $_val) { $tpl->tpl_vars[$_key] = new Smarty_Variable($_val); } } return $tpl; }
/** * modify template_resource according to resource handlers specifications * * @param Smarty_Internal_template $template Smarty instance * @param string $template_resource template_resource to extract resource handler and name of * * @return string unique resource name */ public static function getUniqueTemplateName($template, $template_resource) { $name = $type = null; $smarty = isset($template->smarty) ? $template->smarty : $template; self::parseResourceName($template_resource, $smarty->default_resource_type, $name, $type); // TODO: optimize for Smarty's internal resource types $resource = Smarty_Resource::load($smarty, $type); // go relative to a given template? $_file_is_dotted = $name[0] == '.' && ($name[1] == '.' || $name[1] == '/'); if ($template instanceof Smarty_Internal_Template && $_file_is_dotted && ($template->source->type == 'file' || $template->parent->source->type == 'extends')) { $name = dirname($template->source->filepath) . DS . $name; } return $resource->buildUniqueResourceName($smarty, $name); }
/** * 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) { if ($_template) { $smarty = $_template->smarty; $template_resource = $_template->template_resource; } if (empty($template_resource)) { throw new SmartyException('Missing template name'); } // parse resource_name, load resource handler, identify unique resource name if (preg_match('/^([A-Za-z0-9_\\-]{2,})[:]([\\s\\S]*)$/', $template_resource, $match)) { $type = $match[1]; $name = $match[2]; } else { // no resource given, use default // or single character before the colon is not a resource type, but part of the filepath $type = $smarty->default_resource_type; $name = $template_resource; } $handler = isset($smarty->_cache['resource_handlers'][$type]) ? $smarty->_cache['resource_handlers'][$type] : Smarty_Resource::load($smarty, $type); // create new source object $source = new Smarty_Template_Source($handler, $smarty, $template_resource, $type, $name); $handler->populate($source, $_template); if (!$source->exists && isset($_template->smarty->default_template_handler_func)) { Smarty_Internal_Method_RegisterDefaultTemplateHandler::_getDefaultTemplate($source); } return $source; }
public static function config(Smarty_Internal_Config $_config) { static $_incompatible_resources = array('eval' => true, 'string' => true, 'extends' => true, 'php' => true); $config_resource = $_config->config_resource; $smarty = $_config->smarty; self::parseResourceName($config_resource, $smarty->default_config_type, $name, $type); if (isset($_incompatible_resources[$type])) { throw new SmartyException("Unable to use resource '{$type}' for config"); } $resource = Smarty_Resource::load($smarty, $type); $unique_resource_name = $resource->buildUniqueResourceName($smarty, $name, true); $_cache_key = 'config|' . $unique_resource_name; if (isset(self::$sources[$_cache_key])) { return self::$sources[$_cache_key]; } $source = new Smarty_Config_Source($resource, $smarty, $config_resource, $type, $name, $unique_resource_name); $resource->populate($source, null); self::$sources[$_cache_key] = $source; return $source; }
/** * Template code runtime function to set up an inline subtemplate * * @param \Smarty_Internal_Template $callerTpl * @param string $template template name * @param mixed $cache_id cache id * @param mixed $compile_id compile id * @param integer $caching cache mode * @param integer $cache_lifetime life time of cache data * @param array $data passed parameter template variables * @param int $parent_scope scope in which {include} should execute * @param bool $cache_tpl_obj cache template object * @param string|null $uid source uid * * @return \Smarty_Internal_Template template object * @throws \SmartyException */ public function setupSubtemplate(Smarty_Internal_Template $callerTpl, $template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $cache_tpl_obj, $uid = null) { $_templateId = isset($callerTpl->smarty->_cache['template_objects']) ? $callerTpl->smarty->_getTemplateId($template, $cache_id, $compile_id) : null; // already in template cache? /* @var Smarty_Internal_Template $tpl */ if (isset($callerTpl->smarty->_cache['template_objects'][$_templateId])) { // clone cached template object because of possible recursive call $tpl = clone $callerTpl->smarty->_cache['template_objects'][$_templateId]; $tpl->parent = $callerTpl; if ((bool) $tpl->caching !== (bool) $caching) { unset($tpl->compiled); } // get variables from calling scope if ($parent_scope == Smarty::SCOPE_LOCAL) { $tpl->tpl_vars = $callerTpl->tpl_vars; $tpl->config_vars = $callerTpl->config_vars; } $tpl->tpl_function = $callerTpl->tpl_function; //if (isset($callerTpl->_cache['inheritanceBlocks'])) { // $tpl->_cache['inheritanceBlocks'] = $callerTpl->_cache['inheritanceBlocks']; //} } else { $tpl = clone $callerTpl; $tpl->parent = $callerTpl; $tpl->isChild = false; if (!isset($tpl->templateId) || $tpl->templateId !== $_templateId) { $tpl->templateId = $_templateId; $tpl->template_resource = $template; $tpl->cache_id = $cache_id; $tpl->compile_id = $compile_id; if (isset($uid)) { $tpl->compiled = $callerTpl->compiled; if (isset($tpl->compiled->includes["{$tpl->source->type}:{$tpl->source->name}"]) && $tpl->compiled->includes["{$tpl->source->type}:{$tpl->source->name}"] > 1) { $cache_tpl_obj = true; } if (isset($tpl->compiled->file_dependency[$uid])) { $info = $tpl->compiled->file_dependency[$uid]; $tpl->source = new Smarty_Template_Source(isset($tpl->smarty->_cache['resource_handlers'][$info[2]]) ? $tpl->smarty->_cache['resource_handlers'][$info[2]] : Smarty_Resource::load($tpl->smarty, $info[2]), $tpl->smarty, $info[0], $info[2], $info[0]); $tpl->source->filepath = $info[0]; $tpl->source->timestamp = $info[1]; $tpl->source->exist = true; $tpl->source->uid = $uid; } else { $tpl->source = null; } } else { $tpl->source = null; unset($tpl->compiled); } if (!isset($tpl->source)) { $tpl->source = Smarty_Template_Source::load($tpl); } unset($tpl->cached); // check if template object should be cached if (!$tpl->source->handler->recompiled && (isset($tpl->parent->templateId) && isset($tpl->smarty->_cache['template_objects'][$tpl->parent->templateId]) || $cache_tpl_obj && $tpl->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_AUTOMATIC || $tpl->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON)) { $tpl->smarty->_cache['template_objects'][$tpl->_getTemplateId()] = $tpl; } } } $tpl->caching = $caching; $tpl->cache_lifetime = $cache_lifetime; if ($caching == 9999) { $tpl->cached = $callerTpl->cached; } // get variables from calling scope if ($parent_scope != Smarty::SCOPE_LOCAL) { if ($parent_scope == Smarty::SCOPE_PARENT) { $tpl->tpl_vars =& $callerTpl->tpl_vars; $tpl->config_vars =& $callerTpl->config_vars; } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) { $tpl->tpl_vars =& Smarty::$global_tpl_vars; $tpl->config_vars = $callerTpl->config_vars; } elseif ($parent_scope == Smarty::SCOPE_ROOT) { $ptr = $tpl->parent; while (!empty($ptr->parent)) { $ptr = $ptr->parent; } $tpl->tpl_vars =& $ptr->tpl_vars; $tpl->config_vars =& $ptr->config_vars; } else { $tpl->tpl_vars = $callerTpl->tpl_vars; $tpl->config_vars = $callerTpl->config_vars; } } if (!empty($data)) { // set up variable values foreach ($data as $_key => $_val) { $tpl->tpl_vars[$_key] = new Smarty_Variable($_val); } } return $tpl; }
/** * 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) { if ($_template) { $smarty = $_template->smarty; $template_resource = $_template->template_resource; } if (empty($template_resource)) { throw new SmartyException('Missing template name'); } // parse resource_name, load resource handler, identify unique resource name if (preg_match('/^([A-Za-z0-9_\\-]{2,})[:]([\\s\\S]*)$/', $template_resource, $match)) { $type = $match[1]; $name = $match[2]; } else { // no resource given, use default // or single character before the colon is not a resource type, but part of the filepath $type = $smarty->default_resource_type; $name = $template_resource; } $handler = isset($smarty->_cache['resource_handlers'][$type]) ? $smarty->_cache['resource_handlers'][$type] : Smarty_Resource::load($smarty, $type); // if resource is not recompiling and resource name is not dotted we can check the source cache if ($smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON && !$handler->recompiled && !(isset($name[1]) && $name[0] == '.' && ($name[1] == '.' || $name[1] == '/'))) { $unique_resource = $handler->buildUniqueResourceName($smarty, $name); if (isset($smarty->_cache['source_objects'][$unique_resource])) { return $smarty->_cache['source_objects'][$unique_resource]; } } else { $unique_resource = null; } // create new source object $source = new Smarty_Template_Source($handler, $smarty, $template_resource, $type, $name); $handler->populate($source, $_template); if (!$source->exists && isset($_template->smarty->default_template_handler_func)) { Smarty_Internal_Method_RegisterDefaultTemplateHandler::_getDefaultTemplate($source); } // on recompiling resources we are done if ($smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON && !$handler->recompiled) { // may by we have already $unique_resource $is_relative = false; if (!isset($unique_resource)) { $is_relative = isset($name[1]) && $name[0] == '.' && ($name[1] == '.' || $name[1] == '/') && ($type == 'file' || isset($_template->parent->source) && $_template->parent->source->type == 'extends'); $unique_resource = $handler->buildUniqueResourceName($smarty, $is_relative ? $source->filepath . $name : $name); } $source->unique_resource = $unique_resource; // save in runtime cache if not relative if (!$is_relative) { $smarty->_cache['source_objects'][$unique_resource] = $source; } } return $source; }
/** * 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 = ['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 list($name, $type) = Smarty_Resource::parseResourceName($template_resource, $smarty->default_config_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; }
/** * modify template_resource according to resource handlers specifications * * @param \Smarty_Internal_Template|\Smarty $obj Smarty instance * @param string $template_resource template_resource to extract resource handler and name of * * @return string unique resource name */ public static function getUniqueTemplateName($obj, $template_resource) { $smarty = $obj->_objType == 2 ? $obj->smarty : $obj; list($name, $type) = self::parseResourceName($template_resource, $smarty->default_resource_type); // TODO: optimize for Smarty's internal resource types $resource = Smarty_Resource::load($smarty, $type); // go relative to a given template? $_file_is_dotted = $name[0] == '.' && ($name[1] == '.' || $name[1] == '/'); if ($obj->_objType == 2 && $_file_is_dotted && ($obj->source->type == 'file' || $obj->parent->source->type == 'extends')) { $name = dirname($obj->source->filepath) . DS . $name; } return $resource->buildUniqueResourceName($smarty, $name); }
/** * create Source Object container * * @param Smarty_Resource $handler Resource Handler this source object communicates with * @param Smarty $smarty Smarty instance this source object belongs to * @param string $resource full template_resource * @param string $type type of resource * @param string $name resource name * */ public function __construct(Smarty $smarty, $resource, $type, $name) { $this->handler = isset($smarty->_cache['resource_handlers'][$type]) ? $smarty->_cache['resource_handlers'][$type] : Smarty_Resource::load($smarty, $type); $this->smarty = $smarty; $this->resource = $resource; $this->type = $type; $this->name = $name; }
/** * Compiles code for the {include} tag * * @param array $args array with attributes from parser * @param Smarty_Internal_SmartyTemplateCompiler $compiler compiler object * @param array $parameter array with compilation parameter * * @throws SmartyCompilerException * @return string compiled code */ public function compile($args, Smarty_Internal_SmartyTemplateCompiler $compiler, $parameter) { $uid = $t_hash = null; // check and get attributes $_attr = $this->getAttributes($compiler, $args); $fullResourceName = $source_resource = $_attr['file']; $variable_template = false; $cache_tpl = false; // parse resource_name if (preg_match('/^([\'"])(([A-Za-z0-9_\\-]{2,})[:])?(([^$()]+)|(.+))\\1$/', $source_resource, $match)) { $type = !empty($match[3]) ? $match[3] : $compiler->template->smarty->default_resource_type; $name = !empty($match[5]) ? $match[5] : $match[6]; $handler = Smarty_Resource::load($compiler->smarty, $type); if ($handler->recompiled || $handler->uncompiled) { $variable_template = true; } if (!$variable_template) { if ($type != 'string') { $fullResourceName = "{$type}:{$name}"; $compiled = $compiler->parent_compiler->template->compiled; if (isset($compiled->includes[$fullResourceName])) { $compiled->includes[$fullResourceName]++; $cache_tpl = true; } else { if ("{$compiler->template->source->type}:{$compiler->template->source->name}" == $fullResourceName) { // recursive call of current template $compiled->includes[$fullResourceName] = 2; $cache_tpl = true; } else { $compiled->includes[$fullResourceName] = 1; } } $fullResourceName = $match[1] . $fullResourceName . $match[1]; } } if (empty($match[5])) { $variable_template = true; } } else { $variable_template = true; } // scope setup $_scope = $compiler->convertScope($_attr, $this->valid_scopes); // set flag to cache subtemplate object when called within loop or template name is variable. if ($cache_tpl || $variable_template || $compiler->loopNesting > 0) { $_cache_tpl = 'true'; } else { $_cache_tpl = 'false'; } // assume caching is off $_caching = Smarty::CACHING_OFF; $call_nocache = $compiler->tag_nocache || $compiler->nocache; // caching was on and {include} is not in nocache mode if ($compiler->template->caching && !$compiler->nocache && !$compiler->tag_nocache) { $_caching = self::CACHING_NOCACHE_CODE; } // flag if included template code should be merged into caller $merge_compiled_includes = ($compiler->smarty->merge_compiled_includes || $_attr['inline'] === true) && !$compiler->template->source->handler->recompiled; if ($merge_compiled_includes) { // variable template name ? if ($variable_template) { $merge_compiled_includes = false; } // variable compile_id? if (isset($_attr['compile_id']) && $compiler->isVariable($_attr['compile_id'])) { $merge_compiled_includes = false; } } /* * if the {include} tag provides individual parameter for caching or compile_id * the subtemplate must not be included into the common cache file and is treated like * a call in nocache mode. * */ if ($_attr['nocache'] !== true && $_attr['caching']) { $_caching = $_new_caching = (int) $_attr['caching']; $call_nocache = true; } else { $_new_caching = Smarty::CACHING_LIFETIME_CURRENT; } if (isset($_attr['cache_lifetime'])) { $_cache_lifetime = $_attr['cache_lifetime']; $call_nocache = true; $_caching = $_new_caching; } else { $_cache_lifetime = '$_smarty_tpl->cache_lifetime'; } if (isset($_attr['cache_id'])) { $_cache_id = $_attr['cache_id']; $call_nocache = true; $_caching = $_new_caching; } else { $_cache_id = '$_smarty_tpl->cache_id'; } if (isset($_attr['compile_id'])) { $_compile_id = $_attr['compile_id']; } else { $_compile_id = '$_smarty_tpl->compile_id'; } // if subtemplate will be called in nocache mode do not merge if ($compiler->template->caching && $call_nocache) { $merge_compiled_includes = false; } // assign attribute if (isset($_attr['assign'])) { // output will be stored in a smarty variable instead of being displayed if ($_assign = $compiler->getId($_attr['assign'])) { $_assign = "'{$_assign}'"; if ($compiler->tag_nocache || $compiler->nocache || $call_nocache) { // create nocache var to make it know for further compiling $compiler->setNocacheInVariable($_attr['assign']); } } else { $_assign = $_attr['assign']; } } $has_compiled_template = false; if ($merge_compiled_includes) { $c_id = isset($_attr['compile_id']) ? $_attr['compile_id'] : $compiler->template->compile_id; // we must observe different compile_id and caching $t_hash = sha1($c_id . ($_caching ? '--caching' : '--nocaching')); $compiler->smarty->allow_ambiguous_resources = true; /* @var Smarty_Internal_Template $tpl */ $tpl = new $compiler->smarty->template_class(trim($fullResourceName, '"\''), $compiler->smarty, $compiler->template, $compiler->template->cache_id, $c_id, $_caching); $uid = $tpl->source->type . $tpl->source->uid; if (!isset($compiler->parent_compiler->mergedSubTemplatesData[$uid][$t_hash])) { $has_compiled_template = $this->compileInlineTemplate($compiler, $tpl, $t_hash); } else { $has_compiled_template = true; } unset($tpl); } // delete {include} standard attributes unset($_attr['file'], $_attr['assign'], $_attr['cache_id'], $_attr['compile_id'], $_attr['cache_lifetime'], $_attr['nocache'], $_attr['caching'], $_attr['scope'], $_attr['inline']); // remaining attributes must be assigned as smarty variable $_vars = 'array()'; if (!empty($_attr)) { $_pairs = array(); // create variables foreach ($_attr as $key => $value) { $_pairs[] = "'{$key}'=>{$value}"; } $_vars = 'array(' . join(',', $_pairs) . ')'; } $update_compile_id = $compiler->template->caching && !$compiler->tag_nocache && !$compiler->nocache && $_compile_id != '$_smarty_tpl->compile_id'; if ($has_compiled_template && !$call_nocache) { $_output = "<?php\n"; if ($update_compile_id) { $_output .= $compiler->makeNocacheCode("\$_compile_id_save[] = \$_smarty_tpl->compile_id;\n\$_smarty_tpl->compile_id = {$_compile_id};\n"); } if (!empty($_attr) && $_caching == 9999 && $compiler->template->caching) { $_vars_nc = "foreach ({$_vars} as \$ik => \$iv) {\n"; $_vars_nc .= "\$_smarty_tpl->tpl_vars[\$ik] = new Smarty_Variable(\$iv);\n"; $_vars_nc .= "}\n"; $_output .= substr($compiler->processNocacheCode('<?php ' . $_vars_nc . "?>\n", true), 6, -3); } if (isset($_assign)) { $_output .= "ob_start();\n"; } $_output .= "\$_smarty_tpl->_subTemplateRender({$fullResourceName}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_scope}, {$_cache_tpl}, '{$compiler->parent_compiler->mergedSubTemplatesData[$uid][$t_hash]['uid']}', '{$compiler->parent_compiler->mergedSubTemplatesData[$uid][$t_hash]['func']}');\n"; if (isset($_assign)) { $_output .= "\$_smarty_tpl->assign({$_assign}, ob_get_clean());\n"; } if ($update_compile_id) { $_output .= $compiler->makeNocacheCode("\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n"); } $_output .= "?>\n"; return $_output; } if ($call_nocache) { $compiler->tag_nocache = true; } $_output = "<?php "; if ($update_compile_id) { $_output .= "\$_compile_id_save[] = \$_smarty_tpl->compile_id;\n\$_smarty_tpl->compile_id = {$_compile_id};\n"; } // was there an assign attribute if (isset($_assign)) { $_output .= "ob_start();\n"; } $_output .= "\$_smarty_tpl->_subTemplateRender({$fullResourceName}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_scope}, {$_cache_tpl});\n"; if (isset($_assign)) { $_output .= "\$_smarty_tpl->assign({$_assign}, ob_get_clean());\n"; } if ($update_compile_id) { $_output .= "\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n"; } $_output .= "?>\n"; return $_output; }
/** * initialize Config Source Object for given resource * * @param Smarty_Internal_Config $_config config object * @return Smarty_Config_Source Source Object */ public static function config(Smarty_Internal_Config $_config) { static $_incompatible_resources = array('eval' => true, 'string' => true, 'extends' => true, 'php' => true); $config_resource = $_config->config_resource; $smarty = $_config->smarty; // parse resource_name self::parseResourceName($config_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"); } // load resource handler, identify unique resource name $resource = Smarty_Resource::load($smarty, $type); $unique_resource_name = $resource->buildUniqueResourceName($smarty, $name); // check runtime cache $_cache_key = 'config|' . $unique_resource_name; if (isset(self::$sources[$_cache_key])) { return self::$sources[$_cache_key]; } // create source $source = new Smarty_Config_Source($resource, $smarty, $config_resource, $type, $name, $unique_resource_name); $resource->populate($source, null); // runtime cache self::$sources[$_cache_key] = $source; return $source; }
/** * 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 $name = $type = null; 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); if ($smarty->resource_caching) { $unique_resource = $resource->buildUniqueResourceName($smarty, $name, true); if (isset($smarty->source_objects[$unique_resource])) { return $smarty->source_objects[$unique_resource]; } } else { $unique_resource = null; } $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); } $source->unique_resource = $resource->buildUniqueResourceName($smarty, $name, true); $smarty->source_objects[$source->unique_resource] = $source; return $source; }