/** * render template * * @param bool $display true: display, false: fetch * @param bool $isSubTemplate * @param bool $runOutputFilter * @param null|\Smarty_Internal_Context $_contextObjIn optional buffer object * * @return string * @throws \SmartyException */ public function render($display = false, $isSubTemplate = false, $runOutputFilter = true, Smarty_Internal_Context $_contextObjIn = null) { $level = ob_get_level(); try { if (!isset($this->source)) { $this->source = Smarty_Template_Source::load($this); } // checks if template exists if (!$this->source->exists) { if ($this->parent instanceof Smarty_Internal_Template) { $parent_resource = " in '{$this->parent->template_resource}'"; } else { $parent_resource = ''; } throw new SmartyException("Unable to load template {$this->source->type} '{$this->source->name}'{$parent_resource}"); } if ($this->smarty->debugging) { Smarty_Internal_Debug::start_template($this); } $this->context = $_contextObjIn === null ? new Smarty_Internal_Context() : $_contextObjIn; // merge all variable scopes into template if (!$isSubTemplate) { $savedErrorLevel = isset($this->smarty->error_reporting) ? error_reporting($this->smarty->error_reporting) : null; // save local variables $savedTplVars = $this->tpl_vars; $savedConfigVars = $this->config_vars; $ptr_array = array($this); $ptr = $this; while (isset($ptr->parent)) { $ptr_array[] = $ptr = $ptr->parent; } $ptr_array = array_reverse($ptr_array); $parent_ptr = reset($ptr_array); $tpl_vars = $parent_ptr->tpl_vars; $config_vars = $parent_ptr->config_vars; while ($parent_ptr = next($ptr_array)) { if (!empty($parent_ptr->tpl_vars)) { $tpl_vars = array_merge($tpl_vars, $parent_ptr->tpl_vars); } if (!empty($parent_ptr->config_vars)) { $config_vars = array_merge($config_vars, $parent_ptr->config_vars); } } if (!empty(Smarty::$global_tpl_vars)) { $tpl_vars = array_merge(Smarty::$global_tpl_vars, $tpl_vars); } $this->tpl_vars = $tpl_vars; $this->config_vars = $config_vars; } else { $savedTplVars = null; $savedConfigVars = null; $savedErrorLevel = null; } // dummy local smarty variable if (!isset($this->tpl_vars['smarty'])) { $this->tpl_vars['smarty'] = new Smarty_Variable(); } // disable caching for evaluated code if ($this->source->recompiled) { $this->caching = false; } $_caching = $this->caching == Smarty::CACHING_LIFETIME_CURRENT || $this->caching == Smarty::CACHING_LIFETIME_SAVED; // read from cache or render if ($_caching && !isset($this->cached)) { $this->cached = Smarty_Template_Cached::load($this); } if (!$_caching || !$this->cached->valid) { // render template (not loaded and not in cache) if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($this, null); } if (isset($this->cached)) { $_savedContext = $this->context; $this->context = new Smarty_Internal_Context(true); } if (!$this->source->uncompiled) { // render compiled code if (!isset($this->compiled)) { $this->compiled = Smarty_Template_Compiled::load($this); } $this->compiled->render($this); } else { $this->source->renderUncompiled($this); } if ($this->smarty->debugging) { Smarty_Internal_Debug::end_render($this, null); } // write to cache when necessary if ($_caching && !$this->source->recompiled) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_cache($this); } // write cache file content if ($runOutputFilter && !$this->context->hasNocacheCode && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) { $this->cached->writeCachedContent($this, $this->context, Smarty_Internal_Filter_Handler::runFilter('output', $this->context->getContent(), $this)); } else { $this->cached->writeCachedContent($this, $this->context); } $this->context = $_savedContext; $compile_check = $this->smarty->compile_check; $this->smarty->compile_check = false; if (!$this->cached->processed) { $this->cached->process($this); } $this->smarty->compile_check = $compile_check; $this->cached->compiledTplObj->getRenderedTemplateCode($this); if ($this->smarty->debugging) { Smarty_Internal_Debug::end_cache($this); } } } else { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_cache($this); } $this->cached->render($this); if ($this->smarty->debugging) { Smarty_Internal_Debug::end_cache($this); } } if ($runOutputFilter && (!$this->caching || $this->context->hasNocacheCode || $this->source->recompiled) && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) { $this->context->flushBuffer(); $this->context->content = Smarty_Internal_Filter_Handler::runFilter('output', $this->context->content, $this); } // display or fetch if ($display) { $this->context->endBuffer(); if ($this->caching && $this->smarty->cache_modified_check) { $this->cached->cacheModifiedCheck($this, $this->context->content); } else { echo $this->context->content; } $this->context = null; } if ($this->smarty->debugging) { Smarty_Internal_Debug::end_template($this); } if ($display) { // debug output if ($this->smarty->debugging) { Smarty_Internal_Debug::display_debug($this, true); } } if (!$isSubTemplate) { // restore local variables $this->tpl_vars = $savedTplVars; $this->config_vars = $savedConfigVars; if (isset($savedErrorLevel)) { error_reporting($savedErrorLevel); } } } catch (Exception $e) { while (ob_get_level() > $level) { ob_end_clean(); } throw $e; } if (!$display && $_contextObjIn === null) { // return fetched content $this->context->endBuffer(); $output = $this->context->content; $this->context = null; return $output; } $this->context = null; return ''; }
/** * Writes the content to cache resource * * @param Smarty_Internal_Template $_template * @param \Smarty_Internal_Context $context * @param string $content * * @return bool */ public function writeCachedContent(Smarty_Internal_Template $_template, Smarty_Internal_Context $context = null, $content = '') { if ($_template->source->recompiled || !($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED)) { // don't write cache file return false; } $properties = array('isCache' => true, 'cacheLifetime' => $_template->cache_lifetime); if ($context) { $properties['resourceInfo'] = $context->resourceInfo; if ($context->hasNocacheCode) { $properties['hasNocacheCode'] = true; } foreach ($context->templateFunctions as $name => $data) { unset($data['obj']); $properties['templateFunctions'][$name] = $data; } if (!empty($context->nocachePlugins)) { $properties['plugins'] = $context->nocachePlugins; } $content = !empty($content) ? $content : $context->getContent(); } return $this->write($_template, Smarty_Internal_Extension_CodeFrame::create($_template, $properties, $content, '', true)); }