diff --git a/phpBB/includes/functions_template.php b/phpBB/includes/functions_template.php index 18291c8026..16d708e2d6 100644 --- a/phpBB/includes/functions_template.php +++ b/phpBB/includes/functions_template.php @@ -39,6 +39,7 @@ class template_filter extends php_user_filter $data = $this->chunk . substr($bucket->data, 0, $last_nl); $this->chunk = substr($bucket->data, $last_nl); $bucket->data = $this->compile($data); + $bucket->datalen = strlen($bucket->data); $consumed += $bucket->datalen; stream_bucket_append($out, $bucket); } @@ -441,6 +442,7 @@ class template_filter extends php_user_filter return 'unset(' . (($match[1]) ? $this->generate_block_data_ref(substr($match[1], 0, -1), true, true) . '[\'' . $match[2] . '\']' : '$this->_tpldata[\'DEFINE\'][\'.\'][\'' . $match[2] . '\']') . ');'; } + $varrefs = array(); // Are we a string? if ($match[3] && $match[5]) { @@ -452,6 +454,11 @@ class template_filter extends php_user_filter // Now replace the php code $match[4] = "'" . str_replace(array(''), array("' . ", " . '"), $match[4]) . "'"; } + // is this a template variable? + else if (preg_match('#^((?:[a-z0-9\-_]+\.)+)?(\$)?(?=[A-Z])([A-Z0-9\-_]+)#s', $match[4], $varrefs)) + { + $match[4] = (!empty($varrefs[1])) ? $this->generate_block_data_ref(substr($varrefs[1], 0, -1), true, $varrefs[2]) . '[\'' . $varrefs[3] . '\']' : (($varrefs[2]) ? '$this->_tpldata[\'DEFINE\'][\'.\'][\'' . $varrefs[3] . '\']' : '$this->_rootref[\'' . $varrefs[3] . '\']'); + } else { $type = array(); @@ -639,7 +646,7 @@ stream_filter_register('template', 'template_filter'); * psoTFX, phpBB Development Team - Completion of file caching, decompilation * routines and implementation of conditionals/keywords and associated changes * -* The interface was inspired by PHPLib templates, and the template file (formats are +* The interface was inspired by PHPLib templates, and the template file (formats are * quite similar) * * The keyword/conditional implementation is currently based on sections of code from @@ -679,10 +686,22 @@ class template_compile } // Actually compile the code now. - $this->compile_write($handle, $this->template->files[$handle]); + return $this->compile_write($handle, $this->template->files[$handle]); } + public function _tpl_gen_src($handle) + { + // Try and open template for read + if (!file_exists($this->template->files[$handle])) + { + trigger_error("template->_tpl_load_file(): File {$this->template->files[$handle]} does not exist or is empty", E_USER_ERROR); + } + + // Actually compile the code now. + return $this->compile_gen(/*$handle, */$this->template->files[$handle]); + } + /** * Write compiled file to cache directory * @access private @@ -694,9 +713,9 @@ class template_compile $source_handle = @fopen($source_file, 'rb'); $destination_handle = @fopen($filename, 'wb'); - if(!$source_handle || !$destination_handle) + if (!$source_handle || !$destination_handle) { - return; + return false; } stream_filter_append($destination_handle, 'template'); @@ -711,6 +730,37 @@ class template_compile @fclose($destination_handle); @fclose($source_handle); @chmod($filename, 0666); + + return true; + } + + /** + * Generate source for eval() + * @access private + */ + private function compile_gen(/*$handle, */$source_file) + { + $source_handle = @fopen($source_file, 'rb'); + $destination_handle = @fopen('php://temp' ,'r+b'); + + if (!$source_handle || !$destination_handle) + { + return false; + } + + stream_filter_append($destination_handle, 'template'); + + while (!feof($source_handle)) + { + @fwrite($destination_handle, fread($source_handle, self::BUFFER)); + } + @fwrite($destination_handle, "\n"); + @fwrite($destination_handle, "\n"); + + @fclose($source_handle); + + rewind($destination_handle); + return stream_get_contents($destination_handle); } } diff --git a/phpBB/includes/template.php b/phpBB/includes/template.php index cd74ef8ff2..01de64d4c4 100644 --- a/phpBB/includes/template.php +++ b/phpBB/includes/template.php @@ -139,8 +139,6 @@ class template public function display($handle, $include_once = true) { global $user, $phpbb_hook; - // $user _is_ used the included files. - $user; if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, __FUNCTION__), $handle, $include_once)) { @@ -158,9 +156,22 @@ class template } }*/ - $filename = $this->_tpl_load($handle); - - ($include_once) ? include_once($filename) : include($filename); + if (($filename = $this->_tpl_load($handle)) !== false) + { + // $user _is_ used the included files. + $user; + ($include_once) ? include_once($filename) : include($filename); + } + else if (($code = $this->_tpl_eval($handle)) !== false) + { + $code = ' ?> ' . $code . ' cachepath . str_replace('/', '.', $this->filename[$handle]) . '.' . PHP_EXT; $recompile = (($config['load_tplcompile'] && @filemtime($filename) < filemtime($this->files[$handle])) || !file_exists($filename) || @filesize($filename) === 0) ? true : false; // Recompile page if the original template is newer, otherwise load the compiled version - if (!$recompile) + if ($recompile) { - return $filename; + if (!class_exists('template_compile')) + { + include(PHPBB_ROOT_PATH . 'includes/functions_template.' . PHP_EXT); + } + + $compile = new template_compile($this); + + // If we don't have a file assigned to this handle, die. + if (!isset($this->files[$handle])) + { + trigger_error("template->_tpl_load(): No file specified for handle $handle", E_USER_ERROR); + } + + if ($compile->_tpl_load_file($handle) === false) + { + return false; + } } + return $filename; + } + + /** + * This code should only run when some high level error prevents us from writing to the cache. + * @access private + */ + private function _tpl_eval(&$handle) + { +// global $user, $config; + if (!class_exists('template_compile')) { include(PHPBB_ROOT_PATH . 'includes/functions_template.' . PHP_EXT); @@ -213,18 +251,15 @@ class template // If we don't have a file assigned to this handle, die. if (!isset($this->files[$handle])) { - trigger_error("template->_tpl_load(): No file specified for handle $handle", E_USER_ERROR); + trigger_error("template->_tpl_eval(): No file specified for handle $handle", E_USER_ERROR); } - // Just compile if no user object is present (happens within the installer) - if (!$user) + if (($code = $compile->_tpl_gen_src($handle)) === false) { - $compile->_tpl_load_file($handle); - return $filename; + return false; } - $compile->_tpl_load_file($handle); - return $filename; + return $code; } /** @@ -453,6 +488,21 @@ class template include($filename); return; } + else + { + if (!class_exists('template_compile')) + { + include(PHPBB_ROOT_PATH . 'includes/functions_template.' . PHP_EXT); + } + + $compile = new template_compile($this); + + if (($code = $compile->_tpl_gen_src($handle)) !== false) + { + $code = ' ?> ' . $code . '