diff options
Diffstat (limited to 'phpBB/includes/template')
-rw-r--r-- | phpBB/includes/template/compile.php | 166 | ||||
-rw-r--r-- | phpBB/includes/template/context.php | 359 | ||||
-rw-r--r-- | phpBB/includes/template/filter.php | 1260 | ||||
-rw-r--r-- | phpBB/includes/template/locator.php | 163 | ||||
-rw-r--r-- | phpBB/includes/template/renderer.php | 35 | ||||
-rw-r--r-- | phpBB/includes/template/renderer_eval.php | 60 | ||||
-rw-r--r-- | phpBB/includes/template/renderer_include.php | 60 | ||||
-rw-r--r-- | phpBB/includes/template/template.php | 515 |
8 files changed, 0 insertions, 2618 deletions
diff --git a/phpBB/includes/template/compile.php b/phpBB/includes/template/compile.php deleted file mode 100644 index 76cb3011df..0000000000 --- a/phpBB/includes/template/compile.php +++ /dev/null @@ -1,166 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -stream_filter_register('phpbb_template', 'phpbb_template_filter'); - -/** -* Extension of template class - Functions needed for compiling templates only. -* -* @package phpBB3 -* @uses template_filter As a PHP stream filter to perform compilation of templates -*/ -class phpbb_template_compile -{ - /** - * Array of parameters to forward to template filter - * - * @var array - */ - private $filter_params; - - /** - * Array of default parameters - * - * @var array - */ - private $default_filter_params; - - /** - * Constructor. - * - * @param bool $allow_php Whether PHP code will be allowed in templates (inline PHP code, PHP tag and INCLUDEPHP tag) - * @param array $style_names Name of style to which the template being compiled belongs and parents in style tree order - * @param phpbb_style_resource_locator $locator Resource locator - * @param string $phpbb_root_path Path to phpBB root directory - * @param phpbb_extension_manager $extension_manager Extension manager to use for finding template fragments in extensions; if null, template events will not be invoked - * @param phpbb_user $user Current user - */ - public function __construct($allow_php, $style_names, $locator, $phpbb_root_path, $extension_manager = null, $user = null) - { - $this->filter_params = $this->default_filter_params = array( - 'allow_php' => $allow_php, - 'style_names' => $style_names, - 'locator' => $locator, - 'phpbb_root_path' => $phpbb_root_path, - 'extension_manager' => $extension_manager, - 'user' => $user, - 'template_compile' => $this, - 'cleanup' => true, - ); - } - - /** - * Set filter parameters - * - * @param array $params Array of parameters (will be merged onto $this->filter_params) - */ - public function set_filter_params($params) - { - $this->filter_params = array_merge( - $this->filter_params, - $params - ); - } - - /** - * Reset filter parameters to their default settings - */ - public function reset_filter_params() - { - $this->filter_params = $this->default_filter_params; - } - - /** - * Compiles template in $source_file and writes compiled template to - * cache directory - * - * @param string $handle Template handle to compile - * @param string $source_file Source template file - * @return bool Return true on success otherwise false - */ - public function compile_file_to_file($source_file, $compiled_file) - { - $lock = new phpbb_lock_flock($compiled_file); - $lock->acquire(); - - $source_handle = @fopen($source_file, 'rb'); - $destination_handle = @fopen($compiled_file, 'wb'); - - if (!$source_handle || !$destination_handle) - { - return false; - } - - $this->compile_stream_to_stream($source_handle, $destination_handle); - - @fclose($source_handle); - @fclose($destination_handle); - - phpbb_chmod($compiled_file, CHMOD_READ | CHMOD_WRITE); - - $lock->release(); - - clearstatcache(); - - return true; - } - - /** - * Compiles a template located at $source_file. - * - * Returns PHP source suitable for eval(). - * - * @param string $source_file Source template file - * @return string|bool Return compiled code on successful compilation otherwise false - */ - public function compile_file($source_file) - { - $source_handle = @fopen($source_file, 'rb'); - $destination_handle = @fopen('php://temp' ,'r+b'); - - if (!$source_handle || !$destination_handle) - { - return false; - } - - $this->compile_stream_to_stream($source_handle, $destination_handle); - - @fclose($source_handle); - - rewind($destination_handle); - $contents = stream_get_contents($destination_handle); - @fclose($dest_handle); - - return $contents; - } - - /** - * Compiles contents of $source_stream into $dest_stream. - * - * A stream filter is appended to $source_stream as part of the - * process. - * - * @param resource $source_stream Source stream - * @param resource $dest_stream Destination stream - * @return null - */ - private function compile_stream_to_stream($source_stream, $dest_stream) - { - stream_filter_append($source_stream, 'phpbb_template', null, $this->filter_params); - stream_copy_to_stream($source_stream, $dest_stream); - } -} diff --git a/phpBB/includes/template/context.php b/phpBB/includes/template/context.php deleted file mode 100644 index ec09da1cf3..0000000000 --- a/phpBB/includes/template/context.php +++ /dev/null @@ -1,359 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* Stores variables assigned to template. -* -* @package phpBB3 -*/ -class phpbb_template_context -{ - /** - * variable that holds all the data we'll be substituting into - * the compiled templates. Takes form: - * --> $this->tpldata[block][iteration#][child][iteration#][child2][iteration#][variablename] == value - * if it's a root-level variable, it'll be like this: - * --> $this->tpldata[.][0][varname] == value - * - * @var array - */ - private $tpldata = array('.' => array(0 => array())); - - /** - * @var array Reference to template->tpldata['.'][0] - */ - private $rootref; - - public function __construct() - { - $this->clear(); - } - - /** - * Clears template data set. - */ - public function clear() - { - $this->tpldata = array('.' => array(0 => array())); - $this->rootref = &$this->tpldata['.'][0]; - } - - /** - * Assign a single scalar value to a single key. - * - * Value can be a string, an integer or a boolean. - * - * @param string $varname Variable name - * @param string $varval Value to assign to variable - */ - public function assign_var($varname, $varval) - { - $this->rootref[$varname] = $varval; - - return true; - } - - /** - * Append text to the string value stored in a key. - * - * Text is appended using the string concatenation operator (.). - * - * @param string $varname Variable name - * @param string $varval Value to append to variable - */ - public function append_var($varname, $varval) - { - $this->rootref[$varname] = (isset($this->rootref[$varname]) ? $this->rootref[$varname] : '') . $varval; - - return true; - } - - /** - * Returns a reference to template data array. - * - * This function is public so that template renderer may invoke it. - * Users should alter template variables via functions in phpbb_template. - * - * Note: modifying returned array will affect data stored in the context. - * - * @return array template data - */ - public function &get_data_ref() - { - // returning a reference directly is not - // something php is capable of doing - $ref = &$this->tpldata; - return $ref; - } - - /** - * Returns a reference to template root scope. - * - * This function is public so that template renderer may invoke it. - * Users should not need to invoke this function. - * - * Note: modifying returned array will affect data stored in the context. - * - * @return array template data - */ - public function &get_root_ref() - { - // rootref is already a reference - return $this->rootref; - } - - /** - * Assign key variable pairs from an array to a specified block - * - * @param string $blockname Name of block to assign $vararray to - * @param array $vararray A hash of variable name => value pairs - */ - public function assign_block_vars($blockname, array $vararray) - { - if (strpos($blockname, '.') !== false) - { - // Nested block. - $blocks = explode('.', $blockname); - $blockcount = sizeof($blocks) - 1; - - $str = &$this->tpldata; - for ($i = 0; $i < $blockcount; $i++) - { - $str = &$str[$blocks[$i]]; - $str = &$str[sizeof($str) - 1]; - } - - $s_row_count = isset($str[$blocks[$blockcount]]) ? sizeof($str[$blocks[$blockcount]]) : 0; - $vararray['S_ROW_COUNT'] = $s_row_count; - - // Assign S_FIRST_ROW - if (!$s_row_count) - { - $vararray['S_FIRST_ROW'] = true; - } - - // Now the tricky part, we always assign S_LAST_ROW and remove the entry before - // This is much more clever than going through the complete template data on display (phew) - $vararray['S_LAST_ROW'] = true; - if ($s_row_count > 0) - { - unset($str[$blocks[$blockcount]][($s_row_count - 1)]['S_LAST_ROW']); - } - - // Now we add the block that we're actually assigning to. - // We're adding a new iteration to this block with the given - // variable assignments. - $str[$blocks[$blockcount]][] = $vararray; - } - else - { - // Top-level block. - $s_row_count = (isset($this->tpldata[$blockname])) ? sizeof($this->tpldata[$blockname]) : 0; - $vararray['S_ROW_COUNT'] = $s_row_count; - - // Assign S_FIRST_ROW - if (!$s_row_count) - { - $vararray['S_FIRST_ROW'] = true; - } - - // We always assign S_LAST_ROW and remove the entry before - $vararray['S_LAST_ROW'] = true; - if ($s_row_count > 0) - { - unset($this->tpldata[$blockname][($s_row_count - 1)]['S_LAST_ROW']); - } - - // Add a new iteration to this block with the variable assignments we were given. - $this->tpldata[$blockname][] = $vararray; - } - - return true; - } - - /** - * Change already assigned key variable pair (one-dimensional - single loop entry) - * - * An example of how to use this function: - * {@example alter_block_array.php} - * - * @param string $blockname the blockname, for example 'loop' - * @param array $vararray the var array to insert/add or merge - * @param mixed $key Key to search for - * - * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] - * - * int: Position [the position to change or insert at directly given] - * - * If key is false the position is set to 0 - * If key is true the position is set to the last entry - * - * @param string $mode Mode to execute (valid modes are 'insert' and 'change') - * - * If insert, the vararray is inserted at the given position (position counting from zero). - * If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new value). - * - * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) - * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars) - * - * @return bool false on error, true on success - */ - public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') - { - if (strpos($blockname, '.') !== false) - { - // Nested block. - $blocks = explode('.', $blockname); - $blockcount = sizeof($blocks) - 1; - - $block = &$this->tpldata; - for ($i = 0; $i < $blockcount; $i++) - { - if (($pos = strpos($blocks[$i], '[')) !== false) - { - $name = substr($blocks[$i], 0, $pos); - - if (strpos($blocks[$i], '[]') === $pos) - { - $index = sizeof($block[$name]) - 1; - } - else - { - $index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1); - } - } - else - { - $name = $blocks[$i]; - $index = sizeof($block[$name]) - 1; - } - $block = &$block[$name]; - $block = &$block[$index]; - } - - $block = &$block[$blocks[$i]]; // Traverse the last block - } - else - { - // Top-level block. - $block = &$this->tpldata[$blockname]; - } - - // Change key to zero (change first position) if false and to last position if true - if ($key === false || $key === true) - { - $key = ($key === false) ? 0 : sizeof($block); - } - - // Get correct position if array given - if (is_array($key)) - { - // Search array to get correct position - list($search_key, $search_value) = @each($key); - - $key = NULL; - foreach ($block as $i => $val_ary) - { - if ($val_ary[$search_key] === $search_value) - { - $key = $i; - break; - } - } - - // key/value pair not found - if ($key === NULL) - { - return false; - } - } - - // Insert Block - if ($mode == 'insert') - { - // Make sure we are not exceeding the last iteration - if ($key >= sizeof($this->tpldata[$blockname])) - { - $key = sizeof($this->tpldata[$blockname]); - unset($this->tpldata[$blockname][($key - 1)]['S_LAST_ROW']); - $vararray['S_LAST_ROW'] = true; - } - else if ($key === 0) - { - unset($this->tpldata[$blockname][0]['S_FIRST_ROW']); - $vararray['S_FIRST_ROW'] = true; - } - - // Re-position template blocks - for ($i = sizeof($block); $i > $key; $i--) - { - $block[$i] = $block[$i-1]; - } - - // Insert vararray at given position - $block[$key] = $vararray; - - return true; - } - - // Which block to change? - if ($mode == 'change') - { - if ($key == sizeof($block)) - { - $key--; - } - - $block[$key] = array_merge($block[$key], $vararray); - - return true; - } - - return false; - } - - /** - * Reset/empty complete block - * - * @param string $blockname Name of block to destroy - */ - public function destroy_block_vars($blockname) - { - if (strpos($blockname, '.') !== false) - { - // Nested block. - $blocks = explode('.', $blockname); - $blockcount = sizeof($blocks) - 1; - - $str = &$this->tpldata; - for ($i = 0; $i < $blockcount; $i++) - { - $str = &$str[$blocks[$i]]; - $str = &$str[sizeof($str) - 1]; - } - - unset($str[$blocks[$blockcount]]); - } - else - { - // Top-level block. - unset($this->tpldata[$blockname]); - } - - return true; - } -} diff --git a/phpBB/includes/template/filter.php b/phpBB/includes/template/filter.php deleted file mode 100644 index f2bd442010..0000000000 --- a/phpBB/includes/template/filter.php +++ /dev/null @@ -1,1260 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2011 phpBB Group, sections (c) 2001 ispi of Lincoln Inc -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* The template filter that does the actual compilation -* -* 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 -* quite similar) -* -* The keyword/conditional implementation is currently based on sections of code from -* the Smarty templating engine (c) 2001 ispi of Lincoln, Inc. which is released -* (on its own and in whole) under the LGPL. Section 3 of the LGPL states that any code -* derived from an LGPL application may be relicenced under the GPL, this applies -* to this source -* -* DEFINE directive inspired by a request by Cyberalien -* -* @see template_compile -* @package phpBB3 -*/ -class phpbb_template_filter extends php_user_filter -{ - const REGEX_NS = '[a-z_][a-z_0-9]+'; - - const REGEX_VAR = '[A-Z_][A-Z_0-9]+'; - const REGEX_VAR_SUFFIX = '[A-Z_0-9]+'; - - const REGEX_TAG = '<!-- ([A-Z][A-Z_0-9]+)(?: (.*?) ?)?-->'; - - const REGEX_TOKENS = '~<!-- ([A-Z][A-Z_0-9]+)(?: (.*?) ?)?-->|{((?:[a-z_][a-z_0-9]+\.)*\\$?[A-Z][A-Z_0-9]+)}~'; - - /** - * @var array - */ - private $block_names = array(); - - /** - * @var array - */ - private $block_else_level = array(); - - /** - * @var string - */ - private $chunk; - - /** - * @var bool - */ - private $in_php; - - /** - * Whether inline PHP code, <!-- PHP --> and <!-- INCLUDEPHP --> tags - * are allowed. If this is false all PHP code will be silently - * removed from the template during compilation. - * - * @var bool - */ - private $allow_php; - - /** - * Whether cleanup will be performed on resulting code, see compile() - * (Preserve whitespace) - * - * @var bool - */ - private $cleanup = true; - - /** - * Resource locator. - * - * @var phpbb_template_locator - */ - private $locator; - - /** - * @var string phpBB root path - */ - private $phpbb_root_path; - - /** - * Name of the style that the template being compiled and/or rendered - * belongs to, and its parents, in inheritance tree order. - * - * Used to invoke style-specific template events. - * - * @var array - */ - private $style_names; - - /** - * Extension manager. - * - * @var phpbb_extension_manager - */ - private $extension_manager; - - /** - * Current user - * - * @var phpbb_user - */ - private $user; - - /** - * Template compiler. - * - * @var phpbb_template_compile - */ - private $template_compile; - - /** - * Stream filter - * - * Is invoked for evey chunk of the stream, allowing us - * to work on a chunk at a time, which saves memory. - */ - public function filter($in, $out, &$consumed, $closing) - { - $written = false; - $first = false; - - while ($bucket = stream_bucket_make_writeable($in)) - { - $consumed += $bucket->datalen; - - $data = $this->chunk . $bucket->data; - $last_nl = strrpos($data, "\n"); - $this->chunk = substr($data, $last_nl); - $data = substr($data, 0, $last_nl); - - if (!strlen($data)) - { - continue; - } - - $written = true; - - $data = $this->compile($data); - if (!$first) - { - $data = $this->prepend_preamble($data); - $first = false; - } - $bucket->data = $data; - $bucket->datalen = strlen($bucket->data); - stream_bucket_append($out, $bucket); - } - - if ($closing && strlen($this->chunk)) - { - $written = true; - $bucket = stream_bucket_new($this->stream, $this->compile($this->chunk)); - stream_bucket_append($out, $bucket); - } - - return $written ? PSFS_PASS_ON : PSFS_FEED_ME; - } - - /** - * Initializer, called on creation. - * - * Get the allow_php option, style_names, root directory and locator from params, - * which are passed to stream_filter_append. - * - * @return boolean Returns true - */ - public function onCreate() - { - $this->chunk = ''; - $this->in_php = false; - $this->allow_php = $this->params['allow_php']; - $this->locator = $this->params['locator']; - $this->phpbb_root_path = $this->params['phpbb_root_path']; - $this->style_names = $this->params['style_names']; - $this->extension_manager = $this->params['extension_manager']; - $this->cleanup = $this->params['cleanup']; - if (isset($this->params['user'])) - { - $this->user = $this->params['user']; - } - $this->template_compile = $this->params['template_compile']; - return true; - } - - /** - * Compiles a chunk of template. - * - * The chunk must comprise of one or more complete lines from the source - * template. - * - * @param string $data Chunk of source template to compile - * @return string Compiled PHP/HTML code - */ - private function compile($data) - { - $block_start_in_php = $this->in_php; - - $data = preg_replace('#<(?:[\\?%]|script)#s', '<?php echo\'\\0\';?>', $data); - $data = preg_replace_callback(self::REGEX_TOKENS, array($this, 'replace'), $data); - - // Remove php - if (!$this->allow_php) - { - if ($block_start_in_php - && $this->in_php - && strpos($data, '<!-- PHP -->') === false - && strpos($data, '<!-- ENDPHP -->') === false) - { - // This is just php code - return ''; - } - $data = preg_replace('~^.*?<!-- ENDPHP -->~', '', $data); - $data = preg_replace('~<!-- PHP -->.*?<!-- ENDPHP -->~', '', $data); - $data = preg_replace('~<!-- ENDPHP -->.*?$~', '', $data); - } - - if ($this->cleanup) - { - /* - - Preserve whitespace. - PHP removes a newline after the closing tag (if it's there). - This is by design: - - http://www.php.net/manual/en/language.basic-syntax.phpmode.php - http://www.php.net/manual/en/language.basic-syntax.instruction-separation.php - - - Consider the following template: - - <!-- IF condition --> - some content - <!-- ENDIF --> - - If we were to simply preserve all whitespace, we could simply - replace all "?>" tags with "?>\n". - Doing that, would add additional newlines to the compiled - template in place of the IF and ENDIF statements. These - newlines are unwanted (and one is conditional). The IF and - ENDIF are usually on their own line for ease of reading. - - This replacement preserves newlines only for statements that - are not the only statement on a line. It will NOT preserve - newlines at the end of statements in the above example. - It will preserve newlines in situations like: - - <!-- IF condition -->inline content<!-- ENDIF --> - - */ - - $data = preg_replace('~(?<!^)(<\?php.+(?<!/\*\*/)\?>)$~m', "$1\n", $data); - $data = str_replace('/**/?>', "?>\n", $data); - $data = str_replace('?><?php', '', $data); - } - - return $data; - } - - /** - * Prepends a preamble to compiled template. - * Currently preamble checks if IN_PHPBB is defined and calls exit() if it is not. - * - * @param string $data Compiled template chunk - * @return string Compiled template chunk with preamble prepended - */ - private function prepend_preamble($data) - { - $data = "<?php if (!defined('IN_PHPBB')) exit;" . ((strncmp($data, '<?php', 5) === 0) ? substr($data, 5) : ' ?>' . $data); - return $data; - } - - /** - * Callback for replacing matched tokens with compiled template code. - * - * Compiled template code is an HTML stream with embedded PHP. - * - * @param array $matches Regular expression matches - * @return string compiled template code - */ - private function replace($matches) - { - if ($this->in_php && $matches[1] != 'ENDPHP') - { - return ''; - } - - if (isset($matches[3])) - { - return $this->compile_var_tags($matches[0]); - } - - switch ($matches[1]) - { - case 'BEGIN': - $this->block_else_level[] = false; - return '<?php ' . $this->compile_tag_block($matches[2]) . ' ?>'; - break; - - case 'BEGINELSE': - $this->block_else_level[sizeof($this->block_else_level) - 1] = true; - return '<?php }} else { ?>'; - break; - - case 'END': - array_pop($this->block_names); - return '<?php ' . ((array_pop($this->block_else_level)) ? '}' : '}}') . ' ?>'; - break; - - case 'IF': - return '<?php ' . $this->compile_tag_if($matches[2], false) . ' ?>'; - break; - - case 'ELSE': - return '<?php } else { ?>'; - break; - - case 'ELSEIF': - return '<?php ' . $this->compile_tag_if($matches[2], true) . ' ?>'; - break; - - case 'ENDIF': - return '<?php } ?>'; - break; - - case 'DEFINE': - return '<?php ' . $this->compile_tag_define($matches[2], true) . ' ?>'; - break; - - case 'UNDEFINE': - return '<?php ' . $this->compile_tag_define($matches[2], false) . ' ?>'; - break; - - case 'ENDDEFINE': - return '<?php ' . $this->compile_tag_enddefine() . ' ?>'; - break; - - case 'INCLUDE': - return '<?php ' . $this->compile_tag_include($matches[2]) . ' ?>'; - break; - - case 'INCLUDEPHP': - return ($this->allow_php) ? '<?php ' . $this->compile_tag_include_php($matches[2]) . ' ?>' : ''; - break; - - case 'INCLUDEJS': - return '<?php ' . $this->compile_tag_include_js($matches[2]) . ' ?>'; - break; - - case 'PHP': - if ($this->allow_php) - { - $this->in_php = true; - return '<?php '; - } - return '<!-- PHP -->'; - break; - - case 'ENDPHP': - if ($this->allow_php) - { - $this->in_php = false; - return ' ?>'; - } - return '<!-- ENDPHP -->'; - break; - - case 'EVENT': - return '<?php ' . $this->compile_tag_event($matches[2]) . '?>'; - break; - - default: - return $matches[0]; - break; - - } - return ''; - } - - /** - * Convert template variables into PHP varrefs - * - * @param string $text_blocks Variable reference in source template - * @param bool $is_expr Returns whether the source was an expression type variable (i.e. S_FIRST_ROW) - * @return string PHP variable name - */ - private function get_varref($text_blocks, &$is_expr) - { - // change template varrefs into PHP varrefs - $varrefs = array(); - - // This one will handle varrefs WITH namespaces - preg_match_all('#\{((?:' . self::REGEX_NS . '\.)+)(\$)?(' . self::REGEX_VAR . ')\}#', $text_blocks, $varrefs, PREG_SET_ORDER); - - foreach ($varrefs as $var_val) - { - $namespace = $var_val[1]; - $varname = $var_val[3]; - $new = $this->generate_block_varref($namespace, $varname, $is_expr, $var_val[2]); - - $text_blocks = str_replace($var_val[0], $new, $text_blocks); - } - - // Language variables cannot be reduced to a single varref, so they must be skipped - // These two replacements would break language variables, so we can only run them on non-language types - if (strpos($text_blocks, '{L_') === false && strpos($text_blocks, '{LA_') === false) - { - // This will handle the remaining root-level varrefs - $text_blocks = preg_replace('#\{(' . self::REGEX_VAR . ')\}#', "\$_rootref['\\1']", $text_blocks); - $text_blocks = preg_replace('#\{\$(' . self::REGEX_VAR . ')\}#', "\$_tpldata['DEFINE']['.']['\\1']", $text_blocks); - } - - return $text_blocks; - } - - /** - * Parse paths of the form {FOO}/a/{BAR}/b - * - * Note: this method assumes at least one variable in the path, this should - * be checked before this method is called. - * - * @param string $path The path to parse - * @param string $include_type The type of template function to call - * @return string An appropriately formatted string to include in the - * template or an empty string if an expression like S_FIRST_ROW was - * incorrectly used - */ - private function parse_dynamic_path($path, $include_type) - { - $matches = array(); - $replace = array(); - $is_expr = true; - - preg_match_all('#\{((?:' . self::REGEX_NS . '\.)*)(\$)?(' . self::REGEX_VAR . ')\}#', $path, $matches); - foreach ($matches[0] as $var_str) - { - $tmp_is_expr = false; - $var = $this->get_varref($var_str, $tmp_is_expr); - $is_expr = $is_expr && $tmp_is_expr; - $replace[] = "' . $var . '"; - } - - if (!$is_expr) - { - return " \$_template->$include_type('" . str_replace($matches[0], $replace, $path) . "', true);"; - } - else - { - return ''; - } - } - - /** - * Compile variables - * - * @param string $text_blocks Variable reference in source template - * @return string compiled template code - */ - private function compile_var_tags(&$text_blocks) - { - $text_blocks = $this->get_varref($text_blocks, $is_expr); - $lang_replaced = $this->compile_language_tags($text_blocks); - - if(!$lang_replaced) - { - $text_blocks = '<?php echo ' . ($is_expr ? "$text_blocks" : "(isset($text_blocks)) ? $text_blocks : ''") . '; /**/?>'; - } - - return $text_blocks; - } - - /** - * Handles special language tags L_ and LA_ - * - * @param string $text_blocks Variable reference in source template - * @return bool Whether a replacement occurred or not - */ - private function compile_language_tags(&$text_blocks) - { - $replacements = 0; - - // transform vars prefixed by L_ into their language variable pendant if nothing is set within the tpldata array - if (strpos($text_blocks, '{L_') !== false) - { - $text_blocks = preg_replace('#\{L_(' . self::REGEX_VAR_SUFFIX . ')\}#', "<?php echo ((isset(\$_rootref['L_\\1'])) ? \$_rootref['L_\\1'] : ((isset(\$_lang['\\1'])) ? \$_lang['\\1'] : '{ \\1 }')); /**/?>", $text_blocks, -1, $replacements); - return (bool) $replacements; - } - - // Handle addslashed language variables prefixed with LA_ - // If a template variable already exist, it will be used in favor of it... - if (strpos($text_blocks, '{LA_') !== false) - { - $text_blocks = preg_replace('#\{LA_(' . self::REGEX_VAR_SUFFIX . '+)\}#', "<?php echo ((isset(\$_rootref['LA_\\1'])) ? \$_rootref['LA_\\1'] : ((isset(\$_rootref['L_\\1'])) ? addslashes(\$_rootref['L_\\1']) : ((isset(\$_lang['\\1'])) ? addslashes(\$_lang['\\1']) : '{ \\1 }'))); /**/?>", $text_blocks, -1, $replacements); - return (bool) $replacements; - } - - return false; - } - - /** - * Compile blocks - * - * @param string $tag_args Block contents in source template - * @return string compiled template code - */ - private function compile_tag_block($tag_args) - { - $no_nesting = false; - - // Is the designer wanting to call another loop in a loop? - // <!-- BEGIN loop --> - // <!-- BEGIN !loop2 --> - // <!-- END !loop2 --> - // <!-- END loop --> - // 'loop2' is actually on the same nesting level as 'loop' you assign - // variables to it with template->assign_block_vars('loop2', array(...)) - if (strpos($tag_args, '!') === 0) - { - // Count the number if ! occurrences (not allowed in vars) - $no_nesting = substr_count($tag_args, '!'); - $tag_args = substr($tag_args, $no_nesting); - } - - // Allow for control of looping (indexes start from zero): - // foo(2) : Will start the loop on the 3rd entry - // foo(-2) : Will start the loop two entries from the end - // foo(3,4) : Will start the loop on the fourth entry and end it on the fifth - // foo(3,-4) : Will start the loop on the fourth entry and end it four from last - $match = array(); - - if (preg_match('#^([^()]*)\(([\-\d]+)(?:,([\-\d]+))?\)$#', $tag_args, $match)) - { - $tag_args = $match[1]; - - if ($match[2] < 0) - { - $loop_start = '($_' . $tag_args . '_count ' . $match[2] . ' < 0 ? 0 : $_' . $tag_args . '_count ' . $match[2] . ')'; - } - else - { - $loop_start = '($_' . $tag_args . '_count < ' . $match[2] . ' ? $_' . $tag_args . '_count : ' . $match[2] . ')'; - } - - if (!isset($match[3]) || strlen($match[3]) < 1 || $match[3] == -1) - { - $loop_end = '$_' . $tag_args . '_count'; - } - else if ($match[3] >= 0) - { - $loop_end = '(' . ($match[3] + 1) . ' > $_' . $tag_args . '_count ? $_' . $tag_args . '_count : ' . ($match[3] + 1) . ')'; - } - else //if ($match[3] < -1) - { - $loop_end = '$_' . $tag_args . '_count' . ($match[3] + 1); - } - } - else - { - $loop_start = 0; - $loop_end = '$_' . $tag_args . '_count'; - } - - $tag_template_php = ''; - array_push($this->block_names, $tag_args); - - if ($no_nesting !== false) - { - // We need to implode $no_nesting times from the end... - $block = array_slice($this->block_names, -$no_nesting); - } - else - { - $block = $this->block_names; - } - - if (sizeof($block) < 2) - { - // Block is not nested. - $tag_template_php = '$_' . $tag_args . "_count = (isset(\$_tpldata['$tag_args'])) ? sizeof(\$_tpldata['$tag_args']) : 0;"; - $varref = "\$_tpldata['$tag_args']"; - } - else - { - // This block is nested. - // Generate a namespace string for this block. - $namespace = implode('.', $block); - - // Get a reference to the data array for this block that depends on the - // current indices of all parent blocks. - $varref = $this->generate_block_data_ref($namespace, false); - - // Create the for loop code to iterate over this block. - $tag_template_php = '$_' . $tag_args . '_count = (isset(' . $varref . ')) ? sizeof(' . $varref . ') : 0;'; - } - - $tag_template_php .= 'if ($_' . $tag_args . '_count) {'; - - /** - * The following uses foreach for iteration instead of a for loop, foreach is faster but requires PHP to make a copy of the contents of the array which uses more memory - * <code> - * if (!$offset) - * { - * $tag_template_php .= 'foreach (' . $varref . ' as $_' . $tag_args . '_i => $_' . $tag_args . '_val){'; - * } - * </code> - */ - - $tag_template_php .= 'for ($_' . $tag_args . '_i = ' . $loop_start . '; $_' . $tag_args . '_i < ' . $loop_end . '; ++$_' . $tag_args . '_i){'; - $tag_template_php .= '$_' . $tag_args . '_val = &' . $varref . '[$_' . $tag_args . '_i];'; - - return $tag_template_php; - } - - /** - * Compile a general expression - much of this is from Smarty with - * some adaptions for our block level methods - * - * @param string $tag_args Expression (tag arguments) in source template - * @return string compiled template code - */ - private function compile_expression($tag_args) - { - $match = array(); - preg_match_all('/(?: - "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | - \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | - [(),] | - [^\s(),]+)/x', $tag_args, $match); - - $tokens = $match[0]; - $is_arg_stack = array(); - - for ($i = 0, $size = sizeof($tokens); $i < $size; $i++) - { - $token = &$tokens[$i]; - - switch ($token) - { - case '!==': - case '===': - case '<<': - case '>>': - case '|': - case '^': - case '&': - case '~': - case ')': - case ',': - case '+': - case '-': - case '*': - case '/': - case '@': - break; - - case '==': - case 'eq': - $token = '=='; - break; - - case '!=': - case '<>': - case 'ne': - case 'neq': - $token = '!='; - break; - - case '<': - case 'lt': - $token = '<'; - break; - - case '<=': - case 'le': - case 'lte': - $token = '<='; - break; - - case '>': - case 'gt': - $token = '>'; - break; - - case '>=': - case 'ge': - case 'gte': - $token = '>='; - break; - - case '&&': - case 'and': - $token = '&&'; - break; - - case '||': - case 'or': - $token = '||'; - break; - - case '!': - case 'not': - $token = '!'; - break; - - case '%': - case 'mod': - $token = '%'; - break; - - case '(': - array_push($is_arg_stack, $i); - break; - - case 'is': - $is_arg_start = ($tokens[$i-1] == ')') ? array_pop($is_arg_stack) : $i-1; - $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); - - $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); - - array_splice($tokens, $is_arg_start, sizeof($tokens), $new_tokens); - - $i = $is_arg_start; - - // no break - - default: - $varrefs = array(); - if (preg_match('#^((?:' . self::REGEX_NS . '\.)+)?(\$)?(?=[A-Z])([A-Z0-9\-_]+)#s', $token, $varrefs)) - { - if (!empty($varrefs[1])) - { - $namespace = substr($varrefs[1], 0, -1); - $dot_pos = strrchr($namespace, '.'); - if ($dot_pos !== false) - { - $namespace = substr($dot_pos, 1); - } - - // S_ROW_COUNT is deceptive, it returns the current row number not the number of rows - // hence S_ROW_COUNT is deprecated in favour of S_ROW_NUM - switch ($varrefs[3]) - { - case 'S_ROW_NUM': - case 'S_ROW_COUNT': - $token = "\$_${namespace}_i"; - break; - - case 'S_NUM_ROWS': - $token = "\$_${namespace}_count"; - break; - - case 'S_FIRST_ROW': - $token = "(\$_${namespace}_i == 0)"; - break; - - case 'S_LAST_ROW': - $token = "(\$_${namespace}_i == \$_${namespace}_count - 1)"; - break; - - case 'S_BLOCK_NAME': - $token = "'$namespace'"; - break; - - default: - $token = $this->generate_block_data_ref(substr($varrefs[1], 0, -1), true, $varrefs[2]) . '[\'' . $varrefs[3] . '\']'; - $token = '(isset(' . $token . ') ? ' . $token . ' : null)'; - break; - } - } - else - { - $token = ($varrefs[2]) ? '$_tpldata[\'DEFINE\'][\'.\'][\'' . $varrefs[3] . '\']' : '$_rootref[\'' . $varrefs[3] . '\']'; - $token = '(isset(' . $token . ') ? ' . $token . ' : null)'; - } - - } - else if (preg_match('#^\.((?:' . self::REGEX_NS . '\.?)+)$#s', $token, $varrefs)) - { - // Allow checking if loops are set with .loopname - // It is also possible to check the loop count by doing <!-- IF .loopname > 1 --> for example - $blocks = explode('.', $varrefs[1]); - - // If the block is nested, we have a reference that we can grab. - // If the block is not nested, we just go and grab the block from _tpldata - if (sizeof($blocks) > 1) - { - $block = array_pop($blocks); - $namespace = implode('.', $blocks); - $varref = $this->generate_block_data_ref($namespace, true); - - // Add the block reference for the last child. - $varref .= "['" . $block . "']"; - } - else - { - $varref = '$_tpldata'; - - // Add the block reference for the last child. - $varref .= "['" . $blocks[0] . "']"; - } - $token = "(isset($varref) ? sizeof($varref) : 0)"; - } - - break; - } - } - - return $tokens; - } - - /** - * Compile IF tags - * - * @param string $tag_args Expression given with IF in source template - * @param bool $elseif True if compiling an IF tag, false if compiling an ELSEIF tag - * @return string compiled template code - */ - private function compile_tag_if($tag_args, $elseif) - { - $tokens = $this->compile_expression($tag_args); - - $tpl = ($elseif) ? '} else if (' : 'if ('; - - $tpl .= implode(' ', $tokens); - $tpl .= ') { '; - - return $tpl; - } - - /** - * Compile DEFINE tags - * - * @param string $tag_args Expression given with DEFINE in source template - * @param bool $op True if compiling a DEFINE tag, false if compiling an UNDEFINE tag - * @return string compiled template code - */ - private function compile_tag_define($tag_args, $op) - { - $match = array(); - preg_match('#^((?:' . self::REGEX_NS . '\.)+)?\$(?=[A-Z])([A-Z0-9_\-]*)(?: = (.*?))?$#', $tag_args, $match); - - if (!empty($match[2]) && !isset($match[3]) && $op) - { - // DEFINE tag with ENDDEFINE - $array = "\$_tpldata['DEFINE']['.vars']"; - $code = 'ob_start(); '; - $code .= "if (!isset($array)) { $array = array(); } "; - $code .= "{$array}[] = '{$match[2]}'"; - return $code; - } - - if (empty($match[2]) || (!isset($match[3]) && $op)) - { - return ''; - } - - if (!$op) - { - return 'unset(' . (($match[1]) ? $this->generate_block_data_ref(substr($match[1], 0, -1), true, true) . '[\'' . $match[2] . '\']' : '$_tpldata[\'DEFINE\'][\'.\'][\'' . $match[2] . '\']') . ');'; - } - - /* - * Define tags that contain template variables (enclosed in curly brackets) - * need to be treated differently. - */ - if (substr($match[3], 1, 1) == '{' && substr($match[3], -2, 1) == '}') - { - $parsed_statement = implode(' ', $this->compile_expression(substr($match[3], 2, -2))); - } - else - { - $parsed_statement = implode(' ', $this->compile_expression($match[3])); - } - - return (($match[1]) ? $this->generate_block_data_ref(substr($match[1], 0, -1), true, true) . '[\'' . $match[2] . '\']' : '$_tpldata[\'DEFINE\'][\'.\'][\'' . $match[2] . '\']') . ' = ' . $parsed_statement . ';'; - } - - /** - * Compile ENDDEFINE tag - * - * @return string compiled template code - */ - private function compile_tag_enddefine() - { - $array = "\$_tpldata['DEFINE']['.vars']"; - $code = "if (!isset($array) || !sizeof($array)) { trigger_error('ENDDEFINE tag without DEFINE in ' . basename(__FILE__), E_USER_ERROR); }"; - $code .= "\$define_var = array_pop($array); "; - $code .= "\$_tpldata['DEFINE']['.'][\$define_var] = ob_get_clean();"; - return $code; - } - - /** - * Compile INCLUDE tag - * - * @param string $tag_args Expression given with INCLUDE in source template - * @return string compiled template code - */ - private function compile_tag_include($tag_args) - { - // Process dynamic includes - if (strpos($tag_args, '{') !== false) - { - return $this->parse_dynamic_path($tag_args, '_tpl_include'); - } - - return "\$_template->_tpl_include('$tag_args');"; - } - - /** - * Compile INCLUDE_PHP tag - * - * @param string $tag_args Expression given with INCLUDEPHP in source template - * @return string compiled template code - */ - private function compile_tag_include_php($tag_args) - { - if (strpos($tag_args, '{') !== false) - { - return $this->parse_dynamic_path($tag_args, '_php_include'); - } - - return "\$_template->_php_include('$tag_args');"; - } - - /** - * Compile EVENT tag. - * - * $tag_args should be a single string identifying the event. - * The event name can contain letters, numbers and underscores only. - * If an invalid event name is specified, an E_USER_ERROR will be - * triggered. - * - * Event tags are only functional when the template engine has - * an instance of the extension manager. Extension manager would - * be called upon to find all extensions listening for the specified - * event, and to obtain additional template fragments. All such - * template fragments will be compiled and included in the generated - * compiled template code for the current template being compiled. - * - * The above means that whenever an extension is enabled or disabled, - * template cache should be cleared in order to update the compiled - * template code for the active set of template event listeners. - * - * This also means that extensions cannot return different template - * fragments at different times. Once templates are compiled, changing - * such template fragments would have no effect. - * - * @param string $tag_args EVENT tag arguments, as a string - for EVENT this is the event name - * @return string compiled template code - */ - private function compile_tag_event($tag_args) - { - if (!preg_match('/^\w+$/', $tag_args)) - { - // The event location is improperly formatted, - if ($this->user) - { - trigger_error($this->user->lang('ERR_TEMPLATE_EVENT_LOCATION', $tag_args), E_USER_ERROR); - } - else - { - trigger_error(sprintf('The specified template event location <em>[%s]</em> is improperly formatted.', $tag_args), E_USER_ERROR); - } - } - $location = $tag_args; - - if ($this->extension_manager) - { - $finder = $this->extension_manager->get_finder(); - - $files = $finder - ->extension_prefix($location) - ->extension_suffix('.html') - ->extension_directory("/styles/all/template") - ->get_files(); - - foreach ($this->style_names as $style_name) - { - $more_files = $finder - ->extension_prefix($location) - ->extension_suffix('.html') - ->extension_directory("/styles/" . $style_name . "/template") - ->get_files(); - if (!empty($more_files)) - { - $files = array_merge($files, $more_files); - break; - } - } - - $all_compiled = ''; - foreach ($files as $file) - { - $this->template_compile->set_filter_params(array( - 'cleanup' => false, - )); - - $compiled = $this->template_compile->compile_file($file); - - $this->template_compile->reset_filter_params(); - - if ($compiled === false) - { - if ($this->user) - { - trigger_error($this->user->lang('ERR_TEMPLATE_COMPILATION', phpbb_filter_root_path($file)), E_USER_ERROR); - } - else - { - trigger_error(sprintf('The file could not be compiled: %s', phpbb_filter_root_path($file)), E_USER_ERROR); - } - } - - $all_compiled .= $compiled; - } - // Need spaces inside php tags as php cannot grok - // < ?php? > sans the spaces - return ' ?' . '>' . $all_compiled . '<?php '; - } - } - - /** - * parse expression - * This is from Smarty - */ - private function _parse_is_expr($is_arg, $tokens) - { - $expr_end = 0; - $negate_expr = false; - - if (($first_token = array_shift($tokens)) == 'not') - { - $negate_expr = true; - $expr_type = array_shift($tokens); - } - else - { - $expr_type = $first_token; - } - - switch ($expr_type) - { - case 'even': - if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') - { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "!(($is_arg / $expr_arg) & 1)"; - } - else - { - $expr = "!($is_arg & 1)"; - } - break; - - case 'odd': - if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') - { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "(($is_arg / $expr_arg) & 1)"; - } - else - { - $expr = "($is_arg & 1)"; - } - break; - - case 'div': - if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') - { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "!($is_arg % $expr_arg)"; - } - break; - } - - if ($negate_expr) - { - if ($expr[0] == '!') - { - // Negated expression, de-negate it. - $expr = substr($expr, 1); - } - else - { - $expr = "!($expr)"; - } - } - - array_splice($tokens, 0, $expr_end, $expr); - - return $tokens; - } - - /** - * Compile INCLUDEJS tag - * - * @param string $tag_args Expression given with INCLUDEJS in source template - * @return string compiled template code - */ - private function compile_tag_include_js($tag_args) - { - // Process dynamic includes - if (strpos($tag_args, '{') !== false) - { - return $this->parse_dynamic_path($tag_args, '_js_include'); - } - - // Locate file - $filename = $this->locator->get_first_file_location(array($tag_args), false, true); - - if ($filename === false) - { - // File does not exist, find it during run time - return ' $_template->_js_include(\'' . addslashes($tag_args) . '\', true); '; - } - - if (substr($filename, 0, strlen($this->phpbb_root_path)) != $this->phpbb_root_path) - { - // Absolute path, include as is - return ' $_template->_js_include(\'' . addslashes($filename) . '\', false, false); '; - } - - // Relative path, remove root path from it - $filename = substr($filename, strlen($this->phpbb_root_path)); - return ' $_template->_js_include(\'' . addslashes($filename) . '\', false, true); '; - } - - /** - * Generates a reference to the given variable inside the given (possibly nested) - * block namespace. This is a string of the form: - * ' . $_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['varname'] . ' - * It's ready to be inserted into an "echo" line in one of the templates. - * - * @param string $namespace Namespace to access (expects a trailing "." on the namespace) - * @param string $varname Variable name to use - * @param bool $expr Returns whether the source was an expression type - * @param bool $defop If true this is a variable created with the DEFINE construct, otherwise template variable - * @return string Code to access variable or echo it if $echo is true - */ - private function generate_block_varref($namespace, $varname, &$expr, $defop = false) - { - // Strip the trailing period. - $namespace = substr($namespace, 0, -1); - - if (($pos = strrpos($namespace, '.')) !== false) - { - $local_namespace = substr($namespace, $pos + 1); - } - else - { - $local_namespace = $namespace; - } - - $expr = true; - - // S_ROW_COUNT is deceptive, it returns the current row number now the number of rows - // hence S_ROW_COUNT is deprecated in favour of S_ROW_NUM - switch ($varname) - { - case 'S_ROW_NUM': - case 'S_ROW_COUNT': - $varref = "\$_${local_namespace}_i"; - break; - - case 'S_NUM_ROWS': - $varref = "\$_${local_namespace}_count"; - break; - - case 'S_FIRST_ROW': - $varref = "(\$_${local_namespace}_i == 0)"; - break; - - case 'S_LAST_ROW': - $varref = "(\$_${local_namespace}_i == \$_${local_namespace}_count - 1)"; - break; - - case 'S_BLOCK_NAME': - $varref = "'$local_namespace'"; - break; - - default: - // Get a reference to the data block for this namespace. - $varref = $this->generate_block_data_ref($namespace, true, $defop); - // Prepend the necessary code to stick this in an echo line. - - // Append the variable reference. - $varref .= "['$varname']"; - - $expr = false; - break; - } - // @todo Test the !$expr more - - return $varref; - } - - /** - * Generates a reference to the array of data values for the given - * (possibly nested) block namespace. This is a string of the form: - * $_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['$childN'] - * - * @param string $blockname Block to access (does not expect a trailing "." on the blockname) - * @param bool $include_last_iterator If $include_last_iterator is true, then [$_childN_i] will be appended to the form shown above. - * @param bool $defop If true this is a variable created with the DEFINE construct, otherwise template variable - * @return string Code to access variable - */ - private function generate_block_data_ref($blockname, $include_last_iterator, $defop = false) - { - // Get an array of the blocks involved. - $blocks = explode('.', $blockname); - $blockcount = sizeof($blocks) - 1; - - // DEFINE is not an element of any referenced variable, we must use _tpldata to access it - if ($defop) - { - $varref = '$_tpldata[\'DEFINE\']'; - // Build up the string with everything but the last child. - for ($i = 0; $i < $blockcount; $i++) - { - $varref .= "['" . $blocks[$i] . "'][\$_" . $blocks[$i] . '_i]'; - } - // Add the block reference for the last child. - $varref .= "['" . $blocks[$blockcount] . "']"; - // Add the iterator for the last child if requried. - if ($include_last_iterator) - { - $varref .= '[$_' . $blocks[$blockcount] . '_i]'; - } - return $varref; - } - else if ($include_last_iterator) - { - return '$_'. $blocks[$blockcount] . '_val'; - } - else - { - return '$_'. $blocks[$blockcount - 1] . '_val[\''. $blocks[$blockcount]. '\']'; - } - } -} diff --git a/phpBB/includes/template/locator.php b/phpBB/includes/template/locator.php deleted file mode 100644 index f6fd20bcc2..0000000000 --- a/phpBB/includes/template/locator.php +++ /dev/null @@ -1,163 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - - -/** -* Resource locator interface. -* -* Objects implementing this interface maintain mapping from template handles -* to source template file paths and locate templates. -* -* Locates style files. -* -* Resource locator is aware of styles tree, and can return actual -* filesystem paths (i.e., the "child" style or the "parent" styles) -* depending on what files exist. -* -* Root paths stored in locator are paths to style directories. Templates are -* stored in subdirectory that $template_path points to. -* -* @package phpBB3 -*/ -interface phpbb_template_locator -{ - /** - * Sets the template filenames for handles. $filename_array - * should be a hash of handle => filename pairs. - * - * @param array $filename_array Should be a hash of handle => filename pairs. - */ - public function set_filenames(array $filename_array); - - /** - * Determines the filename for a template handle. - * - * The filename comes from array used in a set_filenames call, - * which should have been performed prior to invoking this function. - * Return value is a file basename (without path). - * - * @param $handle string Template handle - * @return string Filename corresponding to the template handle - */ - public function get_filename_for_handle($handle); - - /** - * Determines the source file path for a template handle without - * regard for styles tree. - * - * This function returns the path in "primary" style directory - * corresponding to the given template handle. That path may or - * may not actually exist on the filesystem. Because this function - * does not perform stat calls to determine whether the path it - * returns actually exists, it is faster than get_source_file_for_handle. - * - * Use get_source_file_for_handle to obtain the actual path that is - * guaranteed to exist (which might come from the parent style - * directory if primary style has parent styles). - * - * This function will trigger an error if the handle was never - * associated with a template file via set_filenames. - * - * @param $handle string Template handle - * @return string Path to source file path in primary style directory - */ - public function get_virtual_source_file_for_handle($handle); - - /** - * Determines the source file path for a template handle, accounting - * for styles tree and verifying that the path exists. - * - * This function returns the actual path that may be compiled for - * the specified template handle. It will trigger an error if - * the template handle was never associated with a template path - * via set_filenames or if the template file does not exist on the - * filesystem. - * - * Use get_virtual_source_file_for_handle to just resolve a template - * handle to a path without any filesystem or styles tree checks. - * - * @param string $handle Template handle (i.e. "friendly" template name) - * @param bool $find_all If true, each root path will be checked and function - * will return array of files instead of string and will not - * trigger a error if template does not exist - * @return string Source file path - */ - public function get_source_file_for_handle($handle, $find_all = false); - - /** - * Obtains a complete filesystem path for a file in a style. - * - * This function traverses the style tree (selected style and - * its parents in order, if inheritance is being used) and finds - * the first file on the filesystem matching specified relative path, - * or the first of the specified paths if more than one path is given. - * - * This function can be used to determine filesystem path of any - * file under any style, with the consequence being that complete - * relative to the style directory path must be provided as an argument. - * - * In particular, this function can be used to locate templates - * and javascript files. - * - * For locating templates get_first_template_location should be used - * as it prepends the configured template path to the template basename. - * - * Note: "selected style" is whatever style the style resource locator - * is configured for. - * - * The return value then will be a path, relative to the current - * directory or absolute, to the first existing file in the selected - * style or its closest parent. - * - * If the selected style does not have the file being searched, - * (and if inheritance is involved, none of the parents have it either), - * false will be returned. - * - * Multiple files can be specified, in which case the first file in - * the list that can be found on the filesystem is returned. - * - * If multiple files are specified and inheritance is involved, - * first each of the specified files is checked in the selected style, - * then each of the specified files is checked in the immediate parent, - * etc. - * - * Specifying true for $return_default will cause the function to - * return the first path which was checked for existence in the event - * that the template file was not found, instead of false. - * This is always a path in the selected style itself, not any of its - * parents. - * - * If $return_full_path is false, then instead of returning a usable - * path (when the file is found) the file's path relative to the style - * directory will be returned. This is the same path as was given to - * the function as a parameter. This can be used to check which of the - * files specified in $files exists. Naturally this requires passing - * more than one file in $files. - * - * @param array $files List of files to locate. - * @param bool $return_default Determines what to return if file does not - * exist. If true, function will return location where file is - * supposed to be. If false, function will return false. - * @param bool $return_full_path If true, function will return full path - * to file. If false, function will return file name. This - * parameter can be used to check which one of set of files - * is available. - * @return string or boolean Source file path if file exists or $return_default is - * true. False if file does not exist and $return_default is false - */ - public function get_first_file_location($files, $return_default = false, $return_full_path = true); -} diff --git a/phpBB/includes/template/renderer.php b/phpBB/includes/template/renderer.php deleted file mode 100644 index 30e234a733..0000000000 --- a/phpBB/includes/template/renderer.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* Template renderer interface. -* -* Objects implementing this interface encapsulate a means of displaying -* a template. -* -* @package phpBB3 -*/ -interface phpbb_template_renderer -{ - /** - * Displays the template managed by this renderer. - * - * @param phpbb_template_context $context Template context to use - * @param array $lang Language entries to use - */ - public function render($context, $lang); -} diff --git a/phpBB/includes/template/renderer_eval.php b/phpBB/includes/template/renderer_eval.php deleted file mode 100644 index f8e4cb7b10..0000000000 --- a/phpBB/includes/template/renderer_eval.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* Template renderer that stores compiled template's php code and -* displays it via eval. -* -* @package phpBB3 -*/ -class phpbb_template_renderer_eval implements phpbb_template_renderer -{ - /** - * Template code to be eval'ed. - */ - private $code; - - /** - * Constructor. Stores provided code for future evaluation. - * Template includes are delegated to template object $template. - * - * @param string $code php code of the template - * @param phpbb_template $template template object - */ - public function __construct($code, $template) - { - $this->code = $code; - $this->template = $template; - } - - /** - * Displays the template managed by this renderer by eval'ing php code - * of the template. - * - * @param phpbb_template_context $context Template context to use - * @param array $lang Language entries to use - */ - public function render($context, $lang) - { - $_template = $this->template; - $_tpldata = &$context->get_data_ref(); - $_rootref = &$context->get_root_ref(); - $_lang = $lang; - - eval(' ?>' . $this->code . '<?php '); - } -} diff --git a/phpBB/includes/template/renderer_include.php b/phpBB/includes/template/renderer_include.php deleted file mode 100644 index f5c9026abf..0000000000 --- a/phpBB/includes/template/renderer_include.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - - -/** -* Template renderer that stores path to php file with template code -* and displays it by including the file. -* -* @package phpBB3 -*/ -class phpbb_template_renderer_include implements phpbb_template_renderer -{ - /** - * Template path to be included. - */ - private $path; - - /** - * Constructor. Stores path to the template for future inclusion. - * Template includes are delegated to template object $template. - * - * @param string $path path to the template - */ - public function __construct($path, $template) - { - $this->path = $path; - $this->template = $template; - } - - /** - * Displays the template managed by this renderer by including - * the php file containing the template. - * - * @param phpbb_template_context $context Template context to use - * @param array $lang Language entries to use - */ - public function render($context, $lang) - { - $_template = $this->template; - $_tpldata = &$context->get_data_ref(); - $_rootref = &$context->get_root_ref(); - $_lang = $lang; - - include($this->path); - } -} diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php deleted file mode 100644 index bbec768613..0000000000 --- a/phpBB/includes/template/template.php +++ /dev/null @@ -1,515 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2005 phpBB Group, sections (c) 2001 ispi of Lincoln Inc -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* @todo -* IMG_ for image substitution? -* {IMG_[key]:[alt]:[type]} -* {IMG_ICON_CONTACT:CONTACT:full} -> $user->img('icon_contact', 'CONTACT', 'full'); -* -* More in-depth... -* yadayada -*/ - -/** -* Base Template class. -* @package phpBB3 -*/ -class phpbb_template -{ - /** - * Template context. - * Stores template data used during template rendering. - * @var phpbb_template_context - */ - private $context; - - /** - * Path of the cache directory for the template - * @var string - */ - public $cachepath = ''; - - /** - * phpBB root path - * @var string - */ - private $phpbb_root_path; - - /** - * PHP file extension - * @var string - */ - private $php_ext; - - /** - * phpBB config instance - * @var phpbb_config - */ - private $config; - - /** - * Current user - * @var phpbb_user - */ - private $user; - - /** - * Template locator - * @var phpbb_template_locator - */ - private $locator; - - /** - * Extension manager. - * - * @var phpbb_extension_manager - */ - private $extension_manager; - - /** - * Name of the style that the template being compiled and/or rendered - * belongs to, and its parents, in inheritance tree order. - * - * Used to invoke style-specific template events. - * - * @var array - */ - private $style_names; - - /** - * Constructor. - * - * @param string $phpbb_root_path phpBB root path - * @param user $user current user - * @param phpbb_template_locator $locator template locator - * @param phpbb_template_context $context template context - * @param phpbb_extension_manager $extension_manager extension manager, if null then template events will not be invoked - */ - public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_locator $locator, phpbb_template_context $context, phpbb_extension_manager $extension_manager = null) - { - $this->phpbb_root_path = $phpbb_root_path; - $this->php_ext = $php_ext; - $this->config = $config; - $this->user = $user; - $this->locator = $locator; - $this->context = $context; - $this->extension_manager = $extension_manager; - } - - /** - * Sets the template filenames for handles. - * - * @param array $filename_array Should be a hash of handle => filename pairs. - */ - public function set_filenames(array $filename_array) - { - $this->locator->set_filenames($filename_array); - - return true; - } - - /** - * Sets the style names corresponding to style hierarchy being compiled - * and/or rendered. - * - * @param array $style_names List of style names in inheritance tree order - * @return null - */ - public function set_style_names(array $style_names) - { - $this->style_names = $style_names; - } - - /** - * Clears all variables and blocks assigned to this template. - */ - public function destroy() - { - $this->context->clear(); - } - - /** - * Reset/empty complete block - * - * @param string $blockname Name of block to destroy - */ - public function destroy_block_vars($blockname) - { - $this->context->destroy_block_vars($blockname); - } - - /** - * Display a template for provided handle. - * - * The template will be loaded and compiled, if necessary, first. - * - * This function calls hooks. - * - * @param string $handle Handle to display - * @return bool True on success, false on failure - */ - public function display($handle) - { - $result = $this->call_hook($handle, __FUNCTION__); - if ($result !== false) - { - return $result[0]; - } - - return $this->load_and_render($handle); - } - - /** - * Loads a template for $handle, compiling it if necessary, and - * renders the template. - * - * @param string $handle Template handle to render - * @return bool True on success, false on failure - */ - private function load_and_render($handle) - { - $renderer = $this->_tpl_load($handle); - - if ($renderer) - { - $renderer->render($this->context, $this->get_lang()); - return true; - } - else - { - return false; - } - } - - /** - * Calls hook if any is defined. - * - * @param string $handle Template handle being displayed. - * @param string $method Method name of the caller. - */ - private function call_hook($handle, $method) - { - global $phpbb_hook; - - if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, $method), $handle, $this)) - { - if ($phpbb_hook->hook_return(array(__CLASS__, $method))) - { - $result = $phpbb_hook->hook_return_result(array(__CLASS__, $method)); - return array($result); - } - } - - return false; - } - - /** - * Obtains language array. - * This is either lang property of $user property, or if - * it is not set an empty array. - * @return array language entries - */ - public function get_lang() - { - if (isset($this->user->lang)) - { - $lang = $this->user->lang; - } - else - { - $lang = array(); - } - return $lang; - } - - /** - * Display the handle and assign the output to a template variable - * or return the compiled result. - * - * @param string $handle Handle to operate on - * @param string $template_var Template variable to assign compiled handle to - * @param bool $return_content If true return compiled handle, otherwise assign to $template_var - * @return bool|string false on failure, otherwise if $return_content is true return string of the compiled handle, otherwise return true - */ - public function assign_display($handle, $template_var = '', $return_content = true) - { - ob_start(); - $result = $this->display($handle); - $contents = ob_get_clean(); - if ($result === false) - { - return false; - } - - if ($return_content) - { - return $contents; - } - - $this->assign_var($template_var, $contents); - - return true; - } - - /** - * Obtains a template renderer for a template identified by specified - * handle. The template renderer can display the template later. - * - * Template source will first be compiled into php code. - * If template cache is writable the compiled php code will be stored - * on filesystem and template will not be subsequently recompiled. - * If template cache is not writable template source will be recompiled - * every time it is needed. DEBUG define and load_tplcompile - * configuration setting may be used to force templates to be always - * recompiled. - * - * Returns an object implementing phpbb_template_renderer, or null - * if template loading or compilation failed. Call render() on the - * renderer to display the template. This will result in template - * contents sent to the output stream (unless, of course, output - * buffering is in effect). - * - * @param string $handle Handle of the template to load - * @return phpbb_template_renderer Template renderer object, or null on failure - * @uses phpbb_template_compile is used to compile template source - */ - private function _tpl_load($handle) - { - $output_file = $this->_compiled_file_for_handle($handle); - - $recompile = defined('DEBUG') || - !file_exists($output_file) || - @filesize($output_file) === 0; - - if ($recompile || $this->config['load_tplcompile']) - { - // Set only if a recompile or an mtime check are required. - $source_file = $this->locator->get_source_file_for_handle($handle); - - if (!$recompile && @filemtime($output_file) < @filemtime($source_file)) - { - $recompile = true; - } - } - - // Recompile page if the original template is newer, otherwise load the compiled version - if (!$recompile) - { - return new phpbb_template_renderer_include($output_file, $this); - } - - $compile = new phpbb_template_compile($this->config['tpl_allow_php'], $this->style_names, $this->locator, $this->phpbb_root_path, $this->extension_manager, $this->user); - - if ($compile->compile_file_to_file($source_file, $output_file) !== false) - { - $renderer = new phpbb_template_renderer_include($output_file, $this); - } - else if (($code = $compile->compile_file($source_file)) !== false) - { - $renderer = new phpbb_template_renderer_eval($code, $this); - } - else - { - $renderer = null; - } - - return $renderer; - } - - /** - * Determines compiled file path for handle $handle. - * - * @param string $handle Template handle (i.e. "friendly" template name) - * @return string Compiled file path - */ - private function _compiled_file_for_handle($handle) - { - $source_file = $this->locator->get_filename_for_handle($handle); - $compiled_file = $this->cachepath . str_replace('/', '.', $source_file) . '.' . $this->php_ext; - return $compiled_file; - } - - /** - * Assign key variable pairs from an array - * - * @param array $vararray A hash of variable name => value pairs - */ - public function assign_vars(array $vararray) - { - foreach ($vararray as $key => $val) - { - $this->assign_var($key, $val); - } - } - - /** - * Assign a single scalar value to a single key. - * - * Value can be a string, an integer or a boolean. - * - * @param string $varname Variable name - * @param string $varval Value to assign to variable - */ - public function assign_var($varname, $varval) - { - $this->context->assign_var($varname, $varval); - } - - /** - * Append text to the string value stored in a key. - * - * Text is appended using the string concatenation operator (.). - * - * @param string $varname Variable name - * @param string $varval Value to append to variable - */ - public function append_var($varname, $varval) - { - $this->context->append_var($varname, $varval); - } - - // Docstring is copied from phpbb_template_context method with the same name. - /** - * Assign key variable pairs from an array to a specified block - * @param string $blockname Name of block to assign $vararray to - * @param array $vararray A hash of variable name => value pairs - */ - public function assign_block_vars($blockname, array $vararray) - { - return $this->context->assign_block_vars($blockname, $vararray); - } - - // Docstring is copied from phpbb_template_context method with the same name. - /** - * Change already assigned key variable pair (one-dimensional - single loop entry) - * - * An example of how to use this function: - * {@example alter_block_array.php} - * - * @param string $blockname the blockname, for example 'loop' - * @param array $vararray the var array to insert/add or merge - * @param mixed $key Key to search for - * - * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] - * - * int: Position [the position to change or insert at directly given] - * - * If key is false the position is set to 0 - * If key is true the position is set to the last entry - * - * @param string $mode Mode to execute (valid modes are 'insert' and 'change') - * - * If insert, the vararray is inserted at the given position (position counting from zero). - * If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new value). - * - * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) - * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars) - * - * @return bool false on error, true on success - */ - public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') - { - return $this->context->alter_block_array($blockname, $vararray, $key, $mode); - } - - /** - * Include a separate template. - * - * This function is marked public due to the way the template - * implementation uses it. It is actually an implementation function - * and should not be considered part of template class's public API. - * - * @param string $filename Template filename to include - * @param bool $include True to include the file, false to just load it - * @uses template_compile is used to compile uncached templates - */ - public function _tpl_include($filename, $include = true) - { - $this->locator->set_filenames(array($filename => $filename)); - - if (!$this->load_and_render($filename)) - { - // trigger_error cannot be used here, as the output already started - echo 'template->_tpl_include(): Failed including ' . htmlspecialchars($handle) . "\n"; - } - } - - /** - * Include a PHP file. - * - * If a relative path is passed in $filename, it is considered to be - * relative to board root ($phpbb_root_path). Absolute paths are - * also allowed. - * - * This function is marked public due to the way the template - * implementation uses it. It is actually an implementation function - * and should not be considered part of template class's public API. - * - * @param string $filename Path to PHP file to include - */ - public function _php_include($filename) - { - if (phpbb_is_absolute($filename)) - { - $file = $filename; - } - else - { - $file = $this->phpbb_root_path . $filename; - } - - if (!file_exists($file)) - { - // trigger_error cannot be used here, as the output already started - echo 'template->_php_include(): File ' . htmlspecialchars($file) . " does not exist\n"; - return; - } - include($file); - } - - /** - * Include JS file - * - * @param string $file file name - * @param bool $locate True if file needs to be located - * @param bool $relative True if path is relative to phpBB root directory. Ignored if $locate == true - */ - public function _js_include($file, $locate = false, $relative = false) - { - // Locate file - if ($locate) - { - $located = $this->locator->get_first_file_location(array($file), false, true); - if ($located) - { - $file = $located; - } - } - else if ($relative) - { - $file = $this->phpbb_root_path . $file; - } - - $file .= (strpos($file, '?') === false) ? '?' : '&'; - $file .= 'assets_version=' . $this->config['assets_version']; - - // Add HTML code - $code = '<script src="' . htmlspecialchars($file) . '"></script>'; - $this->context->append_var('SCRIPTS', $code); - } -} |