/** * render template * * @param bool $merge_tpl_vars if true parent template variables merged in to local scope * @param bool $no_output_filter if true do not run output filter * @param bool $display true: display, false: fetch null: subtemplate * * @throws Exception * @throws SmartyException * @return string rendered template output */ public function render($merge_tpl_vars = false, $no_output_filter = true, $display = null) { $parentIsTpl = $this->parent instanceof Smarty_Internal_Template; if ($this->smarty->debugging) { Smarty_Internal_Debug::start_template($this, $display); } $save_tpl_vars = null; $save_config_vars = null; // merge all variable scopes into template if ($merge_tpl_vars) { // save local variables $save_tpl_vars = $this->tpl_vars; $save_config_vars = $this->config_vars; $ptr_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; } // dummy local smarty variable if (!isset($this->tpl_vars['smarty'])) { $this->tpl_vars['smarty'] = new Smarty_Variable(); } $_smarty_old_error_level = isset($this->smarty->error_reporting) ? error_reporting($this->smarty->error_reporting) : null; // check URL debugging control if (!$this->smarty->debugging && $this->smarty->debugging_ctrl == 'URL') { Smarty_Internal_Debug::debugUrl($this); } if (!isset($this->source)) { $this->loadSource(); } // checks if template exists if (!$this->source->exists) { if ($parentIsTpl) { $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}"); } // disable caching for evaluated code if ($this->source->recompiled) { $this->caching = false; } // read from cache or render $isCacheTpl = $this->caching == Smarty::CACHING_LIFETIME_CURRENT || $this->caching == Smarty::CACHING_LIFETIME_SAVED; if ($isCacheTpl) { if (!isset($this->cached)) { $this->loadCached(); } $this->cached->isCached($this); } if (!$isCacheTpl || !$this->cached->valid) { if ($isCacheTpl) { $this->properties['tpl_function'] = []; } // render template (not loaded and not in cache) if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($this); } if (!$this->source->uncompiled) { // render compiled code if (!isset($this->compiled)) { $this->loadCompiled(); } $content = $this->compiled->render($this); } else { $content = $this->source->renderUncompiled($this); } if (!$this->source->recompiled && empty($this->properties['file_dependency'][$this->source->uid])) { $this->properties['file_dependency'][$this->source->uid] = [$this->source->filepath, $this->source->timestamp, $this->source->type]; } if ($parentIsTpl) { $this->parent->properties['file_dependency'] = array_merge($this->parent->properties['file_dependency'], $this->properties['file_dependency']); //$this->parent->properties['tpl_function'] = array_merge($this->parent->properties['tpl_function'], $this->properties['tpl_function']); } if ($this->smarty->debugging) { Smarty_Internal_Debug::end_render($this); } // write to cache when necessary if (!$this->source->recompiled && $isCacheTpl) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_cache($this); } $this->cached->updateCache($this, $content, $no_output_filter); $compile_check = $this->smarty->compile_check; $this->smarty->compile_check = false; if ($parentIsTpl) { $this->properties['tpl_function'] = $this->parent->properties['tpl_function']; } if (!$this->cached->processed) { $this->cached->process($this); } $this->smarty->compile_check = $compile_check; $content = $this->getRenderedTemplateCode(); if ($this->smarty->debugging) { Smarty_Internal_Debug::end_cache($this); } } else { if (!empty($this->properties['nocache_hash']) && !empty($this->parent->properties['nocache_hash'])) { // replace nocache_hash $content = str_replace("{$this->properties['nocache_hash']}", $this->parent->properties['nocache_hash'], $content); $this->parent->has_nocache_code = $this->parent->has_nocache_code || $this->has_nocache_code; } } } else { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_cache($this); } $content = $this->cached->render($this); if ($this->smarty->debugging) { Smarty_Internal_Debug::end_cache($this); } } if ((!$this->caching || $this->has_nocache_code || $this->source->recompiled) && !$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) { $content = Smarty_Internal_Filter_Handler::runFilter('output', $content, $this); } if (isset($_smarty_old_error_level)) { error_reporting($_smarty_old_error_level); } // display or fetch if ($display) { if ($this->caching && $this->smarty->cache_modified_check) { $this->cached->cacheModifiedCheck($this, $content); } else { echo $content; } if ($this->smarty->debugging) { Smarty_Internal_Debug::end_template($this); } // debug output if ($this->smarty->debugging) { Smarty_Internal_Debug::display_debug($this, true); } if ($merge_tpl_vars) { // restore local variables $this->tpl_vars = $save_tpl_vars; $this->config_vars = $save_config_vars; } return ''; } else { if ($merge_tpl_vars) { // restore local variables $this->tpl_vars = $save_tpl_vars; $this->config_vars = $save_config_vars; } if ($this->smarty->debugging) { Smarty_Internal_Debug::end_template($this); } if ($this->smarty->debugging == 2 and $display === false) { if ($this->smarty->debugging) { Smarty_Internal_Debug::display_debug($this, true); } } if ($parentIsTpl) { $this->parent->properties['tpl_function'] = array_merge($this->parent->properties['tpl_function'], $this->properties['tpl_function']); foreach ($this->required_plugins as $code => $tmp1) { foreach ($tmp1 as $name => $tmp) { foreach ($tmp as $type => $data) { $this->parent->required_plugins[$code][$name][$type] = $data; } } } } // return cache content return $content; } }
/** * Returns the rendered HTML output * * If the cache is valid the cached content is used, otherwise * the output is rendered from the compiled template or PHP template source * * @return string rendered HTML output */ public function getRenderedTemplate() { // disable caching for evaluated code if ($this->resource_object->isEvaluated) { $this->caching = false; } // checks if template exists $this->isExisting(true); // read from cache or render if ($this->rendered_content === null) { if ($this->isCached) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_cache($this); } $this->rendered_content = $this->cache_resource_object->getCachedContents($this, false); if ($this->smarty->debugging) { Smarty_Internal_Debug::end_cache($this); } } if ($this->isCached === null) { $this->isCached(false); } if (!$this->isCached) { // render template (not loaded and not in cache) $this->renderTemplate(); } } $this->updateParentVariables(); $this->isCached = null; return $this->rendered_content; }
/** * 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 * @param object $parent next higher level of Smarty variables * @param bool $display true: display, false: fetch * @param bool $merge_tpl_vars if true parent template variables merged in to local scope * @param bool $no_output_filter if true do not run output filter * @return string rendered template output */ public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false) { if ($template === null && $this instanceof $this->template_class) { $template = $this; } if (!empty($cache_id) && is_object($cache_id)) { $parent = $cache_id; $cache_id = null; } if ($parent === null && ($this instanceof Smarty || is_string($template))) { $parent = $this; } // create template object if necessary $_template = $template instanceof $this->template_class ? $template : $this->smarty->createTemplate($template, $cache_id, $compile_id, $parent, false); // if called by Smarty object make sure we use current caching status if ($this instanceof Smarty) { $_template->caching = $this->caching; } // merge all variable scopes into template if ($merge_tpl_vars) { // save local variables $save_tpl_vars = $_template->tpl_vars; $save_config_vars = $_template->config_vars; $ptr_array = array($_template); $ptr = $_template; 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); } $_template->tpl_vars = $tpl_vars; $_template->config_vars = $config_vars; } // dummy local smarty variable if (!isset($_template->tpl_vars['smarty'])) { $_template->tpl_vars['smarty'] = new Smarty_Variable(); } if (isset($this->smarty->error_reporting)) { $_smarty_old_error_level = error_reporting($this->smarty->error_reporting); } // check URL debugging control if (!$this->smarty->debugging && $this->smarty->debugging_ctrl == 'URL') { if (isset($_SERVER['QUERY_STRING'])) { $_query_string = $_SERVER['QUERY_STRING']; } else { $_query_string = ''; } if (false !== strpos($_query_string, $this->smarty->smarty_debug_id)) { if (false !== strpos($_query_string, $this->smarty->smarty_debug_id . '=on')) { // enable debugging for this browser session setcookie('SMARTY_DEBUG', true); $this->smarty->debugging = true; } elseif (false !== strpos($_query_string, $this->smarty->smarty_debug_id . '=off')) { // disable debugging for this browser session setcookie('SMARTY_DEBUG', false); $this->smarty->debugging = false; } else { // enable debugging for this page $this->smarty->debugging = true; } } else { if (isset($_COOKIE['SMARTY_DEBUG'])) { $this->smarty->debugging = true; } } } // must reset merge template date $_template->smarty->merged_templates_func = array(); // get rendered template // disable caching for evaluated code if ($_template->source->recompiled) { $_template->caching = false; } // checks if template exists if (!$_template->source->exists) { if ($_template->parent instanceof Smarty_Internal_Template) { $parent_resource = " in '{$_template->parent->template_resource}'"; } else { $parent_resource = ''; } throw new SmartyException("Unable to load template {$_template->source->type} '{$_template->source->name}'{$parent_resource}"); } // read from cache or render if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || !$_template->cached->valid) { // render template (not loaded and not in cache) if (!$_template->source->uncompiled) { $_smarty_tpl = $_template; if ($_template->source->recompiled) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_compile($_template); } $code = $_template->compiler->compileTemplate($_template); if ($this->smarty->debugging) { Smarty_Internal_Debug::end_compile($_template); } if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($_template); } try { ob_start(); eval("?>" . $code); unset($code); } catch (Exception $e) { ob_get_clean(); throw $e; } } else { if (!$_template->compiled->exists || $_template->smarty->force_compile && !$_template->compiled->isCompiled) { $_template->compileTemplateSource(); } if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($_template); } if (!$_template->compiled->loaded) { include $_template->compiled->filepath; if ($_template->mustCompile) { // recompile and load again $_template->compileTemplateSource(); include $_template->compiled->filepath; } $_template->compiled->loaded = true; } else { $_template->decodeProperties($_template->compiled->_properties, false); } try { ob_start(); if (empty($_template->properties['unifunc']) || !is_callable($_template->properties['unifunc'])) { throw new SmartyException("Invalid compiled template for '{$_template->template_resource}'"); } array_unshift($_template->_capture_stack, array()); // // render compiled template // $_template->properties['unifunc']($_template); // any unclosed {capture} tags ? if (isset($_template->_capture_stack[0][0])) { $_template->capture_error(); } array_shift($_template->_capture_stack); } catch (Exception $e) { ob_get_clean(); throw $e; } } } else { if ($_template->source->uncompiled) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($_template); } try { ob_start(); $_template->source->renderUncompiled($_template); } catch (Exception $e) { ob_get_clean(); throw $e; } } else { throw new SmartyException("Resource '{$_template->source}->type' must have 'renderUncompiled' method"); } } $_output = ob_get_clean(); if (!$_template->source->recompiled && empty($_template->properties['file_dependency'][$_template->source->uid])) { $_template->properties['file_dependency'][$_template->source->uid] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type); } if ($_template->parent instanceof Smarty_Internal_Template) { $_template->parent->properties['file_dependency'] = array_merge($_template->parent->properties['file_dependency'], $_template->properties['file_dependency']); foreach ($_template->required_plugins as $code => $tmp1) { foreach ($tmp1 as $name => $tmp) { foreach ($tmp as $type => $data) { $_template->parent->required_plugins[$code][$name][$type] = $data; } } } } if ($this->smarty->debugging) { Smarty_Internal_Debug::end_render($_template); } // write to cache when nessecary if (!$_template->source->recompiled && ($_template->caching == Smarty::CACHING_LIFETIME_SAVED || $_template->caching == Smarty::CACHING_LIFETIME_CURRENT)) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_cache($_template); } $_template->properties['has_nocache_code'] = false; // get text between non-cached items $cache_split = preg_split("!/\\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*\\/(.+?)/\\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*/!s", $_output); // get non-cached items preg_match_all("!/\\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*\\/(.+?)/\\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*/!s", $_output, $cache_parts); $output = ''; // loop over items, stitch back together foreach ($cache_split as $curr_idx => $curr_split) { // escape PHP tags in template content $output .= preg_replace('/(<%|%>|<\\?php|<\\?|\\?>)/', '<?php echo \'$1\'; ?>', $curr_split); if (isset($cache_parts[0][$curr_idx])) { $_template->properties['has_nocache_code'] = true; // remove nocache tags from cache output $output .= preg_replace("!/\\*/?%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*/!", '', $cache_parts[0][$curr_idx]); } } if (!$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) { $output = Smarty_Internal_Filter_Handler::runFilter('output', $output, $_template); } // rendering (must be done before writing cache file because of {function} nocache handling) $_smarty_tpl = $_template; try { ob_start(); eval("?>" . $output); $_output = ob_get_clean(); } catch (Exception $e) { ob_get_clean(); throw $e; } // write cache file content $_template->writeCachedContent($output); if ($this->smarty->debugging) { Smarty_Internal_Debug::end_cache($_template); } } else { // var_dump('renderTemplate', $_template->has_nocache_code, $_template->template_resource, $_template->properties['nocache_hash'], $_template->parent->properties['nocache_hash'], $_output); if (!empty($_template->properties['nocache_hash']) && !empty($_template->parent->properties['nocache_hash'])) { // replace nocache_hash $_output = preg_replace("/{$_template->properties['nocache_hash']}/", $_template->parent->properties['nocache_hash'], $_output); $_template->parent->has_nocache_code = $_template->parent->has_nocache_code || $_template->has_nocache_code; } } } else { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_cache($_template); } try { ob_start(); array_unshift($_template->_capture_stack, array()); // // render cached template // $_template->properties['unifunc']($_template); // any unclosed {capture} tags ? if (isset($_template->_capture_stack[0][0])) { $_template->capture_error(); } array_shift($_template->_capture_stack); $_output = ob_get_clean(); } catch (Exception $e) { ob_get_clean(); throw $e; } if ($this->smarty->debugging) { Smarty_Internal_Debug::end_cache($_template); } } if ((!$this->caching || $_template->source->recompiled) && !$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) { $_output = Smarty_Internal_Filter_Handler::runFilter('output', $_output, $_template); } if (isset($this->error_reporting)) { error_reporting($_smarty_old_error_level); } // display or fetch if ($display) { if ($this->caching && $this->cache_modified_check) { $_isCached = $_template->isCached() && !$_template->has_nocache_code; $_last_modified_date = @substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); if ($_isCached && $_template->cached->timestamp <= strtotime($_last_modified_date)) { switch (PHP_SAPI) { case 'cgi': // php-cgi < 5.3 // php-cgi < 5.3 case 'cgi-fcgi': // php-cgi >= 5.3 // php-cgi >= 5.3 case 'fpm-fcgi': // php-fpm >= 5.3.3 header('Status: 304 Not Modified'); break; case 'cli': if (!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'])) { $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = '304 Not Modified'; } break; default: header('HTTP/1.1 304 Not Modified'); break; } } else { switch (PHP_SAPI) { case 'cli': if (!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'])) { $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = 'Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->cached->timestamp) . ' GMT'; } break; default: header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->cached->timestamp) . ' GMT'); break; } echo $_output; } } else { echo $_output; } // debug output if ($this->smarty->debugging) { Smarty_Internal_Debug::display_debug($this); } if ($merge_tpl_vars) { // restore local variables $_template->tpl_vars = $save_tpl_vars; $_template->config_vars = $save_config_vars; } return; } else { if ($merge_tpl_vars) { // restore local variables $_template->tpl_vars = $save_tpl_vars; $_template->config_vars = $save_config_vars; } // return fetched content return $_output; } }
/** * create Cached Object container * * @param Smarty_Internal_Template $_template template object */ public function __construct(Smarty_Internal_Template $_template) { $this->compile_id = $_template->compile_id; $this->cache_id = $_template->cache_id; $this->source = $_template->source; $_template->cached = $this; $smarty = $_template->smarty; // // load resource handler // $this->handler = $handler = Smarty_CacheResource::load($smarty); // Note: prone to circular references // // check if cache is valid // if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || $_template->source->recompiled) { $handler->populate($this, $_template); return; } while (true) { while (true) { $handler->populate($this, $_template); if ($this->timestamp === false || $smarty->force_compile || $smarty->force_cache) { $this->valid = false; } else { $this->valid = true; } if ($this->valid && $_template->caching == Smarty::CACHING_LIFETIME_CURRENT && $_template->cache_lifetime >= 0 && time() > $this->timestamp + $_template->cache_lifetime) { // lifetime expired $this->valid = false; } if ($this->valid || !$_template->smarty->cache_locking) { break; } if (!$this->handler->locked($_template->smarty, $this)) { $this->handler->acquireLock($_template->smarty, $this); break 2; } } if ($this->valid) { if (!$_template->smarty->cache_locking || $this->handler->locked($_template->smarty, $this) === null) { // load cache file for the following checks if ($smarty->debugging) { Smarty_Internal_Debug::start_cache($_template); } if ($handler->process($_template, $this) === false) { $this->valid = false; } else { $this->processed = true; } if ($smarty->debugging) { Smarty_Internal_Debug::end_cache($_template); } } else { continue; } } else { return; } if ($this->valid && $_template->caching === Smarty::CACHING_LIFETIME_SAVED && $_template->properties['cache_lifetime'] >= 0 && time() > $_template->cached->timestamp + $_template->properties['cache_lifetime']) { $this->valid = false; } if (!$this->valid && $_template->smarty->cache_locking) { $this->handler->acquireLock($_template->smarty, $this); return; } else { return; } } }
/** * Check if cache is valid, lock cache if required * * @param \Smarty_Internal_Template $_template * * @return bool flag true if cache is valid */ public function isCached(Smarty_Internal_Template $_template) { if ($this->valid !== null) { return $this->valid; } while (true) { while (true) { if ($this->exists === false || $_template->smarty->force_compile || $_template->smarty->force_cache) { $this->valid = false; } else { $this->valid = true; } if ($this->valid && $_template->caching == Smarty::CACHING_LIFETIME_CURRENT && $_template->cache_lifetime >= 0 && time() > $this->timestamp + $_template->cache_lifetime) { // lifetime expired $this->valid = false; } if ($this->valid && $_template->source->timestamp > $this->timestamp) { $this->valid = false; } if ($this->valid || !$_template->smarty->cache_locking) { break; } if (!$this->handler->locked($_template->smarty, $this)) { $this->handler->acquireLock($_template->smarty, $this); break 2; } $this->handler->populate($this, $_template); } if ($this->valid) { if (!$_template->smarty->cache_locking || $this->handler->locked($_template->smarty, $this) === null) { // load cache file for the following checks if ($_template->smarty->debugging) { Smarty_Internal_Debug::start_cache($_template); } if ($this->handler->process($_template, $this) === false) { $this->valid = false; } else { $this->processed = true; } if ($_template->smarty->debugging) { Smarty_Internal_Debug::end_cache($_template); } } else { $this->is_locked = true; continue; } } else { return $this->valid; } if ($this->valid && $_template->caching === Smarty::CACHING_LIFETIME_SAVED && $_template->properties['cache_lifetime'] >= 0 && time() > $_template->cached->timestamp + $_template->properties['cache_lifetime']) { $this->valid = false; } if ($_template->smarty->cache_locking) { if (!$this->valid) { $this->handler->acquireLock($_template->smarty, $this); } elseif ($this->is_locked) { $this->handler->releaseLock($_template->smarty, $this); } } return $this->valid; } return $this->valid; }
/** * 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 * @param object $parent next higher level of Smarty variables * @param bool $display true: display, false: fetch * @param bool $merge_tpl_vars if true parent template variables merged in to local scope * @param bool $no_output_filter if true do not run output filter * * @throws Exception * @throws SmartyException * @return string rendered template output */ public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false) { if ($template === null && $this instanceof $this->template_class) { $template = $this; } if ($cache_id !== null && is_object($cache_id)) { $parent = $cache_id; $cache_id = null; } if ($parent === null && ($this instanceof Smarty || is_string($template))) { $parent = $this; } // create template object if necessary $_template = $template instanceof $this->template_class ? $template : $this->smarty->createTemplate($template, $cache_id, $compile_id, $parent, false); // if called by Smarty object make sure we use current caching status if ($this instanceof Smarty) { $_template->caching = $this->caching; } // merge all variable scopes into template if ($merge_tpl_vars) { // save local variables $save_tpl_vars = $_template->tpl_vars; $save_config_vars = $_template->config_vars; $ptr_array = array($_template); $ptr = $_template; 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); } $_template->tpl_vars = $tpl_vars; $_template->config_vars = $config_vars; } // dummy local smarty variable if (!isset($_template->tpl_vars['smarty'])) { $_template->tpl_vars['smarty'] = new Smarty_Variable(); } if (isset($this->smarty->error_reporting)) { $_smarty_old_error_level = error_reporting($this->smarty->error_reporting); } // check URL debugging control if (!$this->smarty->debugging && $this->smarty->debugging_ctrl == 'URL') { if (isset($_SERVER['QUERY_STRING'])) { $_query_string = $_SERVER['QUERY_STRING']; } else { $_query_string = ''; } if (false !== strpos($_query_string, $this->smarty->smarty_debug_id)) { if (false !== strpos($_query_string, $this->smarty->smarty_debug_id . '=on')) { // enable debugging for this browser session setcookie('SMARTY_DEBUG', true); $this->smarty->debugging = true; } elseif (false !== strpos($_query_string, $this->smarty->smarty_debug_id . '=off')) { // disable debugging for this browser session setcookie('SMARTY_DEBUG', false); $this->smarty->debugging = false; } else { // enable debugging for this page $this->smarty->debugging = true; } } else { if (isset($_COOKIE['SMARTY_DEBUG'])) { $this->smarty->debugging = true; } } } // must reset merge template date $_template->smarty->merged_templates_func = array(); // get rendered template // disable caching for evaluated code if ($_template->source->recompiled) { $_template->caching = false; } // checks if template exists if (!$_template->source->exists) { if ($_template->parent instanceof Smarty_Internal_Template) { $parent_resource = " in '{$_template->parent->template_resource}'"; } else { $parent_resource = ''; } throw new SmartyException("Unable to load template {$_template->source->type} '{$_template->source->name}'{$parent_resource}"); } // read from cache or render if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || !$_template->cached->valid) { // render template (not loaded and not in cache) if (!$_template->source->uncompiled) { /** @var Smarty_Internal_Template $_smarty_tpl * used in evaluated code */ $_smarty_tpl = $_template; if ($_template->source->recompiled) { $code = $_template->compiler->compileTemplate($_template); if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($_template); } try { ob_start(); /// dark edit \Dark\SmartyView\SmartyEngine::integrateViewComposers($_template); /// end edit eval("?>" . $code); unset($code); } catch (Exception $e) { ob_get_clean(); throw $e; } } else { if (!$_template->compiled->exists || $_template->smarty->force_compile && !$_template->compiled->isCompiled) { $_template->compileTemplateSource(); $code = file_get_contents($_template->compiled->filepath); eval("?>" . $code); unset($code); $_template->compiled->loaded = true; $_template->compiled->isCompiled = true; } if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($_template); } if (!$_template->compiled->loaded) { include $_template->compiled->filepath; if ($_template->mustCompile) { // recompile and load again $_template->compileTemplateSource(); $code = file_get_contents($_template->compiled->filepath); eval("?>" . $code); unset($code); $_template->compiled->isCompiled = true; } $_template->compiled->loaded = true; } else { $_template->decodeProperties($_template->compiled->_properties, false); } try { ob_start(); if (empty($_template->properties['unifunc']) || !is_callable($_template->properties['unifunc'])) { throw new SmartyException("Invalid compiled template for '{$_template->template_resource}'"); } array_unshift($_template->_capture_stack, array()); /// dark edit \Dark\SmartyView\SmartyEngine::integrateViewComposers($_template); /// end edit // // render compiled template // $_template->properties['unifunc']($_template); // any unclosed {capture} tags ? if (isset($_template->_capture_stack[0][0])) { $_template->capture_error(); } array_shift($_template->_capture_stack); } catch (Exception $e) { ob_get_clean(); throw $e; } } } else { if ($_template->source->uncompiled) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($_template); } try { ob_start(); /// dark edit \Dark\SmartyView\SmartyEngine::integrateViewComposers($_template); /// end edit $_template->source->renderUncompiled($_template); } catch (Exception $e) { ob_get_clean(); throw $e; } } else { throw new SmartyException("Resource '{$_template->source}->type' must have 'renderUncompiled' method"); } } $_output = ob_get_clean(); if ($_template->template_resource == './_footer.html' && empty($_template->tpl_vars['navs']->value)) { $_output = preg_replace('/<a href="' . str_replace("/", "\\/", $_template->tpl_vars['site_url']->value) . '"( target="_blank")?( )?>首页<\\/a>( )?\\|([\\s]+)?(<br \\/>)?(<br>)?/is', "", $_output); $_output = preg_replace('/<a href="' . str_replace("/", "\\/", $_template->tpl_vars['site_url']->value) . '"( target="_blank")?( )?>Home<\\/a>( )?\\|([\\s]+)?(<br \\/>)?(<br>)?/is', "", $_output); } //===调用交互服务器接口文件中js,加载访问统计=== /** * 获取域名->获取ip * 根据IP和域名获取数据库信息(交互服务器上) * ->判断ip是否登录过 * */ // if ($_template->template_resource == './_footer.html') { // $postFun = new CommonController; // $domain = $_SERVER['HTTP_HOST'] ? 'http://' . $_SERVER['HTTP_HOST'] : ''; // $ip_address = ($_SERVER['REMOTE_ADDR']); // $today = date('Y-m-d'); //// $param['domain'] = $domain; //// $param['ip_address'] = $ip_address; // $flag = true; //// $stats_log_info = DB::table('stats_log')->where('ip_address', $ip_address)->where('pc_domain', $domain)->orWhere('mobile_domain', $domain)->first(); // $data = array( // 'pc_domain' => $domain, // 'mobile_domain' => $domain, // ); // $stats_log_info = $postFun->postsend("http://swap.5067.org/stats.php?key=get_stats_log",$data); //获取交互服务器上访问日志 // $stats_log_info= json_decode($stats_log_info); // if (empty($stats_log_info) || $stats_log_info == 'null') {//新增 //// echo '1---<br>'; // $data = array( // 'pc_domain' => $customer_info->pc_domain ? $customer_info->pc_domain : $domain, // 'mobile_domain' => $customer_info->mobile_domain ? $customer_info->mobile_domain : $domain, // ); //// $customer_info = DB::table('customer_info')->where('pc_domain', $domain)->orWhere('mobile_domain', $domain)->select('cus_id', 'pc_domain', 'mobile_domain')->first(); // $customer_info = $postFun->postsend("http://swap.5067.org/stats.php?key=get_customer_info", $data); //获取客户信息 // $customer_info = json_decode($customer_info); // $data = array( // 'pc_domain' => $customer_info->pc_domain ? $customer_info->pc_domain : $domain, // 'mobile_domain' => $customer_info->mobile_domain ? $customer_info->mobile_domain : $domain, // ); //// $stats_log_id = DB::table('stats_log')->insertGetId($data); // $stats_log_id = $postFun->postsend("http://swap.5067.org/stats.php?key=insert_stats_log", $data); //添加用户登录日志 // } else {//判断单日是否已经登录过 //// echo '2---<br>'; // if ($stats_log_info->lasttime != $today) {//不是当日更新为今天日期、并且计数+1 // $stats_log_id = $stats_log_info->id; // $data = array( // 'id' => $stats_log_id, // ); //// DB::table('stats_log')->where('id', $stats_log_info->id)->update($data); // $res = $postFun->postsend("http://swap.5067.org/stats.php?key=update_stats_log", $data); //更新用户登录日志 // } else {//当日已登录 // $flag = FALSE; //不做操作 // } // } // if (!$flag) { //// $stats_info = DB::table('stats')->where('cus_id', $customer_info->cus_id)->first(); // $data = array( // 'cus_id' => $customer_info->cus_id, // ); // $stats_info = $postFun->postsend("http://swap.5067.org/stats.php?key=get_stats", $data); //获取客户访问统计信息 // $stats_info = json_decode($stats_info); // if (empty($stats_info) || $stats_info == 'null') {//统计为空,新增数据 //// echo '2---1---<br>'; // $data3 = array( // 'cus_id' => $customer_info->cus_id, // 'pc_domain' => $customer_info->pc_domain ? $customer_info->pc_domain : $domain, // 'mobile_domain' => $customer_info->mobile_domain ? $customer_info->mobile_domain : $domain, // ); // $stats_id = $postFun->postsend("http://swap.5067.org/stats.php?key=insert_stats", $data3); //添加客户访问统计信息 // $data2 = array( // 'id' => $stats_id, // 'page_count_num' => 1, // 'page_today_num' => 1, // ); // } else {//统计不为空,累加数据 //// echo '2---2---<br>'; // $stats_id = $stats_info->id; // if ($stats_info->lasttime != $today) {//查看lasttime是否为今天,不是今天更新lasttime,并重新统计当日访问数 // $data2 = array( // 'id' => $stats_id, // 'page_count_num' => $stats_info->page_count_num + 1, // 'page_today_num' => 1, // 'lasttime' => 1 // ); // } else {//是当日,累加访问数 // $data2 = array( // 'id' => $stats_id, // 'page_count_num' => $stats_info->page_count_num + 1, // 'page_today_num' => $stats_info->page_today_num + 1 // ); // } // } // $resa = $postFun->postsend("http://swap.5067.org/stats.php?key=update_stats", $data2); //更新客户访问统计信息 // } // } if (!$_template->source->recompiled && empty($_template->properties['file_dependency'][$_template->source->uid])) { $_template->properties['file_dependency'][$_template->source->uid] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type); } if ($_template->parent instanceof Smarty_Internal_Template) { $_template->parent->properties['file_dependency'] = array_merge($_template->parent->properties['file_dependency'], $_template->properties['file_dependency']); foreach ($_template->required_plugins as $code => $tmp1) { foreach ($tmp1 as $name => $tmp) { foreach ($tmp as $type => $data) { $_template->parent->required_plugins[$code][$name][$type] = $data; } } } } if ($this->smarty->debugging) { Smarty_Internal_Debug::end_render($_template); } // write to cache when nessecary if (!$_template->source->recompiled && ($_template->caching == Smarty::CACHING_LIFETIME_SAVED || $_template->caching == Smarty::CACHING_LIFETIME_CURRENT)) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_cache($_template); } $_template->properties['has_nocache_code'] = false; // get text between non-cached items $cache_split = preg_split("!/\\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*\\/(.+?)/\\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*/!s", $_output); // get non-cached items preg_match_all("!/\\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*\\/(.+?)/\\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*/!s", $_output, $cache_parts); $output = ''; // loop over items, stitch back together foreach ($cache_split as $curr_idx => $curr_split) { // escape PHP tags in template content $output .= preg_replace('/(<%|%>|<\\?php|<\\?|\\?>)/', "<?php echo '\$1'; ?>\n", $curr_split); if (isset($cache_parts[0][$curr_idx])) { $_template->properties['has_nocache_code'] = true; // remove nocache tags from cache output $output .= preg_replace("!/\\*/?%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*/!", '', $cache_parts[0][$curr_idx]); } } if (!$no_output_filter && !$_template->has_nocache_code && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) { $output = Smarty_Internal_Filter_Handler::runFilter('output', $output, $_template); } // rendering (must be done before writing cache file because of {function} nocache handling) /** @var Smarty_Internal_Template $_smarty_tpl * used in evaluated code */ $_smarty_tpl = $_template; try { ob_start(); /// dark edit \Dark\SmartyView\SmartyEngine::integrateViewComposers($_template); /// end edit eval("?>" . $output); $_output = ob_get_clean(); } catch (Exception $e) { ob_get_clean(); throw $e; } // write cache file content $_template->writeCachedContent($output); if ($this->smarty->debugging) { Smarty_Internal_Debug::end_cache($_template); } } else { // var_dump('renderTemplate', $_template->has_nocache_code, $_template->template_resource, $_template->properties['nocache_hash'], $_template->parent->properties['nocache_hash'], $_output); if (!empty($_template->properties['nocache_hash']) && !empty($_template->parent->properties['nocache_hash'])) { // replace nocache_hash $_output = str_replace("{$_template->properties['nocache_hash']}", $_template->parent->properties['nocache_hash'], $_output); $_template->parent->has_nocache_code = $_template->parent->has_nocache_code || $_template->has_nocache_code; } } } else { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_cache($_template); } try { ob_start(); /// dark edit \Dark\SmartyView\SmartyEngine::integrateViewComposers($_template); /// end edit array_unshift($_template->_capture_stack, array()); // // render cached template // $_template->properties['unifunc']($_template); // any unclosed {capture} tags ? if (isset($_template->_capture_stack[0][0])) { $_template->capture_error(); } array_shift($_template->_capture_stack); $_output = ob_get_clean(); } catch (Exception $e) { ob_get_clean(); throw $e; } if ($this->smarty->debugging) { Smarty_Internal_Debug::end_cache($_template); } } if ((!$this->caching || $_template->has_nocache_code || $_template->source->recompiled) && !$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) { $_output = Smarty_Internal_Filter_Handler::runFilter('output', $_output, $_template); } if (isset($this->error_reporting)) { error_reporting($_smarty_old_error_level); } // display or fetch if ($display) { if ($this->caching && $this->cache_modified_check) { $_isCached = $_template->isCached() && !$_template->has_nocache_code; $_last_modified_date = @substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); if ($_isCached && $_template->cached->timestamp <= strtotime($_last_modified_date)) { switch (PHP_SAPI) { case 'cgi': // php-cgi < 5.3 // php-cgi < 5.3 case 'cgi-fcgi': // php-cgi >= 5.3 // php-cgi >= 5.3 case 'fpm-fcgi': // php-fpm >= 5.3.3 header('Status: 304 Not Modified'); break; case 'cli': if (!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'])) { $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = '304 Not Modified'; } break; default: header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified'); break; } } else { switch (PHP_SAPI) { case 'cli': if (!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'])) { $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = 'Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->cached->timestamp) . ' GMT'; } break; default: header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->cached->timestamp) . ' GMT'); break; } echo $_output; } } else { echo $_output; } // debug output if ($this->smarty->debugging) { Smarty_Internal_Debug::display_debug($_template); } if ($merge_tpl_vars) { // restore local variables $_template->tpl_vars = $save_tpl_vars; $_template->config_vars = $save_config_vars; } return; } else { if ($merge_tpl_vars) { // restore local variables $_template->tpl_vars = $save_tpl_vars; $_template->config_vars = $save_config_vars; } // return fetched content return $_output; } }
public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false) { if ($template === null && $this instanceof $this->template_class) { $template = $this; } if (!empty($cache_id) && is_object($cache_id)) { $parent = $cache_id; $cache_id = null; } if ($parent === null && ($this instanceof Smarty || is_string($template))) { $parent = $this; } $_template = $template instanceof $this->template_class ? $template : $this->smarty->createTemplate($template, $cache_id, $compile_id, $parent, false); if ($this instanceof Smarty) { $_template->caching = $this->caching; } if ($merge_tpl_vars) { $save_tpl_vars = $_template->tpl_vars; $save_config_vars = $_template->config_vars; $ptr_array = array($_template); $ptr = $_template; 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); } $_template->tpl_vars = $tpl_vars; $_template->config_vars = $config_vars; } if (!isset($_template->tpl_vars['smarty'])) { $_template->tpl_vars['smarty'] = new Smarty_Variable(); } if (isset($this->smarty->error_reporting)) { $_smarty_old_error_level = error_reporting($this->smarty->error_reporting); } if (!$this->smarty->debugging && $this->smarty->debugging_ctrl == 'URL') { if (isset($_SERVER['QUERY_STRING'])) { $_query_string = $_SERVER['QUERY_STRING']; } else { $_query_string = ''; } if (false !== strpos($_query_string, $this->smarty->smarty_debug_id)) { if (false !== strpos($_query_string, $this->smarty->smarty_debug_id . '=on')) { setcookie('SMARTY_DEBUG', true); $this->smarty->debugging = true; } elseif (false !== strpos($_query_string, $this->smarty->smarty_debug_id . '=off')) { setcookie('SMARTY_DEBUG', false); $this->smarty->debugging = false; } else { $this->smarty->debugging = true; } } else { if (isset($_COOKIE['SMARTY_DEBUG'])) { $this->smarty->debugging = true; } } } $_template->smarty->merged_templates_func = array(); if ($_template->source->recompiled) { $_template->caching = false; } if (!$_template->source->exists) { if ($_template->parent instanceof Smarty_Internal_Template) { $parent_resource = " in '{$_template->parent->template_resource}'"; } else { $parent_resource = ''; } throw new SmartyException("Unable to load template {$_template->source->type} '{$_template->source->name}'{$parent_resource}"); } if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || !$_template->cached->valid) { if (!$_template->source->uncompiled) { $_smarty_tpl = $_template; if ($_template->source->recompiled) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_compile($_template); } $code = $_template->compiler->compileTemplate($_template); if ($this->smarty->debugging) { Smarty_Internal_Debug::end_compile($_template); } if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($_template); } try { ob_start(); eval("?>" . $code); unset($code); } catch (Exception $e) { ob_get_clean(); throw $e; } } else { if (!$_template->compiled->exists || $_template->smarty->force_compile && !$_template->compiled->isCompiled) { $_template->compileTemplateSource(); } if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($_template); } if (!$_template->compiled->loaded) { include $_template->compiled->filepath; if ($_template->mustCompile) { $_template->compileTemplateSource(); include $_template->compiled->filepath; } $_template->compiled->loaded = true; } else { $_template->decodeProperties($_template->compiled->_properties, false); } try { ob_start(); if (empty($_template->properties['unifunc']) || !is_callable($_template->properties['unifunc'])) { throw new SmartyException("Invalid compiled template for '{$_template->template_resource}'"); } array_unshift($_template->_capture_stack, array()); $_template->properties['unifunc']($_template); if (isset($_template->_capture_stack[0][0])) { $_template->capture_error(); } array_shift($_template->_capture_stack); } catch (Exception $e) { ob_get_clean(); throw $e; } } } else { if ($_template->source->uncompiled) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($_template); } try { ob_start(); $_template->source->renderUncompiled($_template); } catch (Exception $e) { ob_get_clean(); throw $e; } } else { throw new SmartyException("Resource '{$_template->source}->type' must have 'renderUncompiled' method"); } } $_output = ob_get_clean(); if (!$_template->source->recompiled && empty($_template->properties['file_dependency'][$_template->source->uid])) { $_template->properties['file_dependency'][$_template->source->uid] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type); } if ($_template->parent instanceof Smarty_Internal_Template) { $_template->parent->properties['file_dependency'] = array_merge($_template->parent->properties['file_dependency'], $_template->properties['file_dependency']); foreach ($_template->required_plugins as $code => $tmp1) { foreach ($tmp1 as $name => $tmp) { foreach ($tmp as $type => $data) { $_template->parent->required_plugins[$code][$name][$type] = $data; } } } } if ($this->smarty->debugging) { Smarty_Internal_Debug::end_render($_template); } if (!$_template->source->recompiled && ($_template->caching == Smarty::CACHING_LIFETIME_SAVED || $_template->caching == Smarty::CACHING_LIFETIME_CURRENT)) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_cache($_template); } $_template->properties['has_nocache_code'] = false; $cache_split = preg_split("!/\\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*\\/(.+?)/\\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*/!s", $_output); preg_match_all("!/\\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*\\/(.+?)/\\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*/!s", $_output, $cache_parts); $output = ''; foreach ($cache_split as $curr_idx => $curr_split) { $output .= preg_replace('/(<%|%>|<\\?php|<\\?|\\?>)/', '<?php echo \'$1\'; ?>', $curr_split); if (isset($cache_parts[0][$curr_idx])) { $_template->properties['has_nocache_code'] = true; $output .= preg_replace("!/\\*/?%%SmartyNocache:{$_template->properties['nocache_hash']}%%\\*/!", '', $cache_parts[0][$curr_idx]); } } if (!$no_output_filter && !$_template->has_nocache_code && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) { $output = Smarty_Internal_Filter_Handler::runFilter('output', $output, $_template); } $_smarty_tpl = $_template; try { ob_start(); eval("?>" . $output); $_output = ob_get_clean(); } catch (Exception $e) { ob_get_clean(); throw $e; } $_template->writeCachedContent($output); if ($this->smarty->debugging) { Smarty_Internal_Debug::end_cache($_template); } } else { if (!empty($_template->properties['nocache_hash']) && !empty($_template->parent->properties['nocache_hash'])) { $_output = str_replace("{$_template->properties['nocache_hash']}", $_template->parent->properties['nocache_hash'], $_output); $_template->parent->has_nocache_code = $_template->parent->has_nocache_code || $_template->has_nocache_code; } } } else { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_cache($_template); } try { ob_start(); array_unshift($_template->_capture_stack, array()); $_template->properties['unifunc']($_template); if (isset($_template->_capture_stack[0][0])) { $_template->capture_error(); } array_shift($_template->_capture_stack); $_output = ob_get_clean(); } catch (Exception $e) { ob_get_clean(); throw $e; } if ($this->smarty->debugging) { Smarty_Internal_Debug::end_cache($_template); } } if ((!$this->caching || $_template->has_nocache_code || $_template->source->recompiled) && !$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) { $_output = Smarty_Internal_Filter_Handler::runFilter('output', $_output, $_template); } if (isset($this->error_reporting)) { error_reporting($_smarty_old_error_level); } if ($display) { if ($this->caching && $this->cache_modified_check) { $_isCached = $_template->isCached() && !$_template->has_nocache_code; $_last_modified_date = @substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); if ($_isCached && $_template->cached->timestamp <= strtotime($_last_modified_date)) { switch (PHP_SAPI) { case 'cgi': case 'cgi-fcgi': case 'fpm-fcgi': header('Status: 304 Not Modified'); break; case 'cli': if (!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'])) { $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = '304 Not Modified'; } break; default: header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified'); break; } } else { switch (PHP_SAPI) { case 'cli': if (!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'])) { $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = 'Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->cached->timestamp) . ' GMT'; } break; default: header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->cached->timestamp) . ' GMT'); break; } echo $_output; } } else { echo $_output; } if ($this->smarty->debugging) { Smarty_Internal_Debug::display_debug($this); } if ($merge_tpl_vars) { $_template->tpl_vars = $save_tpl_vars; $_template->config_vars = $save_config_vars; } return; } else { if ($merge_tpl_vars) { $_template->tpl_vars = $save_tpl_vars; $_template->config_vars = $save_config_vars; } return $_output; } }
/** * 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 ''; }
/** * Render the output using the compiled template or the PHP template source * * The rendering process is accomplished by just including the PHP files. * The only exceptions are evaluated templates (string template). Their code has * to be evaluated */ public function renderTemplate() { if ($this->resource_object->usesCompiler) { if ($this->mustCompile() && $this->compiled_template === null) { $this->compileTemplateSource(); } if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($this); } $_smarty_tpl = $this; ob_start(); if ($this->resource_object->isEvaluated) { eval("?>" . $this->compiled_template); } else { include $this->getCompiledFilepath(); // check file dependencies at compiled code if ($this->smarty->compile_check) { if (!empty($this->properties['file_dependency'])) { $this->mustCompile = false; foreach ($this->properties['file_dependency'] as $_file_to_check) { $this->getResourceTypeName($_file_to_check[0], $resource_type, $resource_name); if ($resource_type == 'file') { $mtime = filemtime($_file_to_check[0]); } else { $resource_handler = $this->loadTemplateResourceHandler($resource_type); $mtime = $resource_handler->getTemplateTimestampTypeName($resource_type, $resource_name); } // If ($mtime != $_file_to_check[1]) { if ($mtime > $_file_to_check[1]) { $this->mustCompile = true; break; } } if ($this->mustCompile) { // recompile and render again ob_get_clean(); $this->compileTemplateSource(); ob_start(); include $this->getCompiledFilepath(); } } } } } else { if (is_callable(array($this->resource_object, 'renderUncompiled'))) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($this); } ob_start(); $this->resource_object->renderUncompiled($this); } else { throw new Exception("Resource '{$this->resource_type}' must have 'renderUncompiled' methode"); } } $this->rendered_content = ob_get_clean(); if (!$this->resource_object->isEvaluated && empty($this->properties['file_dependency'][$this->templateUid])) { $this->properties['file_dependency'][$this->templateUid] = array($this->getTemplateFilepath(), $this->getTemplateTimestamp()); } if ($this->parent instanceof Smarty_Template or $this->parent instanceof Smarty_Internal_Template) { $this->parent->properties['file_dependency'] = array_merge($this->parent->properties['file_dependency'], $this->properties['file_dependency']); $this->parent->required_plugins['compiled'] = array_merge($this->parent->required_plugins['compiled'], $this->required_plugins['compiled']); $this->parent->required_plugins['cache'] = array_merge($this->parent->required_plugins['cache'], $this->required_plugins['cache']); } if ($this->smarty->debugging) { Smarty_Internal_Debug::end_render($this); } // write to cache when nessecary if (!$this->resource_object->isEvaluated && ($this->caching == SMARTY_CACHING_LIFETIME_SAVED || $this->caching == SMARTY_CACHING_LIFETIME_CURRENT)) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_cache($this); } $this->properties['has_nocache_code'] = false; // get text between non-cached items $cache_split = preg_split("!/\\*%%SmartyNocache:{$this->properties['nocache_hash']}%%\\*\\/(.+?)/\\*/%%SmartyNocache:{$this->properties['nocache_hash']}%%\\*/!s", $this->rendered_content); // get non-cached items preg_match_all("!/\\*%%SmartyNocache:{$this->properties['nocache_hash']}%%\\*\\/(.+?)/\\*/%%SmartyNocache:{$this->properties['nocache_hash']}%%\\*/!s", $this->rendered_content, $cache_parts); $output = ''; // loop over items, stitch back together foreach ($cache_split as $curr_idx => $curr_split) { // escape PHP tags in template content $output .= preg_replace('/(<%|%>|<\\?php|<\\?|\\?>)/', '<?php echo \'$1\'; ?>', $curr_split); if (isset($cache_parts[0][$curr_idx])) { $this->properties['has_nocache_code'] = true; // remove nocache tags from cache output $output .= preg_replace("!/\\*/?%%SmartyNocache:{$this->properties['nocache_hash']}%%\\*/!", '', $cache_parts[0][$curr_idx]); } } // rendering (must be done before writing cache file because of {function} nocache handling) $_smarty_tpl = $this; ob_start(); eval("?>" . $output); $this->rendered_content = ob_get_clean(); // write cache file content $this->writeCachedContent($output); if ($this->smarty->debugging) { Smarty_Internal_Debug::end_cache($this); } } else { // var_dump('renderTemplate', $this->has_nocache_code, $this->template_resource, $this->properties['nocache_hash'], $this->parent->properties['nocache_hash'], $this->rendered_content); if ($this->has_nocache_code && !empty($this->properties['nocache_hash']) && !empty($this->parent->properties['nocache_hash'])) { // replace nocache_hash $this->rendered_content = preg_replace("/{$this->properties['nocache_hash']}/", $this->parent->properties['nocache_hash'], $this->rendered_content); $this->parent->has_nocache_code = $this->has_nocache_code; } } }
/** * @param Smarty_Internal_Template $_template * * @return Smarty_Template_Cached */ static function load(Smarty_Internal_Template $_template) { $_template->cached = $cached = new Smarty_Template_Cached($_template); // // check if cache is valid // if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || $_template->source->recompiled) { $cached->handler->populate($cached, $_template); return $cached; } while (true) { while (true) { $cached->handler->populate($cached, $_template); if ($cached->timestamp === false || $_template->smarty->force_compile || $_template->smarty->force_cache) { $cached->valid = false; } else { $cached->valid = true; } if ($cached->valid && $_template->caching == Smarty::CACHING_LIFETIME_CURRENT && $_template->cache_lifetime >= 0 && time() > $cached->timestamp + $_template->cache_lifetime) { // lifetime expired $cached->valid = false; } if ($cached->valid || !$_template->smarty->cache_locking) { break; } if (!$cached->handler->locked($_template->smarty, $cached)) { $cached->handler->acquireLock($_template->smarty, $cached); break 2; } } if ($cached->valid) { if (!$_template->smarty->cache_locking || $cached->handler->locked($_template->smarty, $cached) === null) { // load cache file for the following checks if ($_template->smarty->debugging) { Smarty_Internal_Debug::start_cache($_template); } $cached->process($_template); if ($_template->smarty->debugging) { Smarty_Internal_Debug::end_cache($_template); } } else { continue; } } else { return $cached; } if ($cached->valid && $_template->caching === Smarty::CACHING_LIFETIME_SAVED && $_template->properties['cache_lifetime'] >= 0 && time() > $_template->cached->timestamp + $_template->properties['cache_lifetime']) { $cached->valid = false; } if (!$cached->valid && $_template->smarty->cache_locking) { $cached->handler->acquireLock($_template->smarty, $cached); return $cached; } else { return $cached; } } }
/** * Render the output using the compiled template or the PHP template source * * The rendering process is accomplished by just including the PHP files. * The only exceptions are evaluated templates (string template). Their code has * to be evaluated */ public function renderTemplate() { if ($this->usesCompiler()) { if ($this->mustCompile() && $this->compiled_template === null) { $this->compileTemplateSource(); } if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($this); } $_smarty_tpl = $this; ob_start(); if ($this->isEvaluated()) { eval("?>" . $this->compiled_template); } else { include $this->getCompiledFilepath(); // check file dependencies at compiled code if ($this->smarty->compile_check) { if (!empty($this->properties['file_dependency'])) { $this->mustCompile = false; foreach ($this->properties['file_dependency'] as $_file_to_check) { $this->getResourceTypeName($_file_to_check[0], $resource_type, $resource_name); if ($resource_type == 'file') { $mtime = filemtime($_file_to_check[0]); } else { $resource_handler = $this->loadTemplateResourceHandler($resource_type); $mtime = $resource_handler->getTemplateTimestampTypeName($resource_type, $resource_name); } // If ($mtime != $_file_to_check[1]) { if ($mtime > $_file_to_check[1]) { $this->properties['file_dependency'] = array(); $this->mustCompile = true; break; } } if ($this->mustCompile) { // recompile and render again ob_get_clean(); $this->compileTemplateSource(); ob_start(); include $this->getCompiledFilepath(); } } } } } else { if (is_callable(array($this->resource_object, 'renderUncompiled'))) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_render($this); } ob_start(); $this->resource_object->renderUncompiled($this); } else { throw new Exception("Resource '{$this->resource_type}' must have 'renderUncompiled' methode"); } } $this->rendered_content = ob_get_clean(); if (!$this->isEvaluated) { $this->properties['file_dependency']['F' . abs(crc32($this->getTemplateFilepath()))] = array($this->getTemplateFilepath(), $this->getTemplateTimestamp()); } if ($this->parent instanceof Smarty_Template or $this->parent instanceof Smarty_Internal_Template) { // var_dump('merge ', $this->parent->getTemplateFilepath(), $this->parent->properties['file_dependency'], $this->getTemplateFilepath(), $this->properties['file_dependency']); $this->parent->properties['file_dependency'] = array_merge($this->parent->properties['file_dependency'], $this->properties['file_dependency']); } if ($this->smarty->debugging) { Smarty_Internal_Debug::end_render($this); } // write to cache when nessecary if (!$this->isEvaluated() && ($this->caching == SMARTY_CACHING_LIFETIME_SAVED || $this->caching == SMARTY_CACHING_LIFETIME_CURRENT)) { if ($this->smarty->debugging) { Smarty_Internal_Debug::start_cache($this); } // write rendered template $this->writeCachedContent($this); // cache file may contain nocache code. read it back for processing $this->rendered_content = $this->cache_resource_object->getCachedContents($this); if ($this->smarty->debugging) { Smarty_Internal_Debug::end_cache($this); } } }