Merge remote-tracking branch 'github-noxwizard/ticket/10322' into develop

* github-noxwizard/ticket/10322:
  [ticket/10322] Separate template varref resolution from output generation
  [ticket/10322] Dynamic template include test
  [ticket/10322] Fix dynamic template includes
This commit is contained in:
Nils Adermann 2011-09-18 22:27:22 +02:00
commit bf5d453479
8 changed files with 85 additions and 16 deletions

View file

@ -307,12 +307,13 @@ class phpbb_template_filter extends php_user_filter
} }
/** /**
* Compile variables * Convert template variables into PHP varrefs
* *
* @param string $text_blocks Variable reference in source template * @param string $text_blocks Variable reference in source template
* @return string compiled template code * @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 compile_var_tags(&$text_blocks) private function get_varref($text_blocks, &$is_expr)
{ {
// change template varrefs into PHP varrefs // change template varrefs into PHP varrefs
$varrefs = array(); $varrefs = array();
@ -324,17 +325,38 @@ class phpbb_template_filter extends php_user_filter
{ {
$namespace = $var_val[1]; $namespace = $var_val[1];
$varname = $var_val[3]; $varname = $var_val[3];
$new = $this->generate_block_varref($namespace, $varname, true, $var_val[2]); $new = $this->generate_block_varref($namespace, $varname, $is_expr, $var_val[2]);
$text_blocks = str_replace($var_val[0], $new, $text_blocks); $text_blocks = str_replace($var_val[0], $new, $text_blocks);
} }
// Handle special language tags L_ and LA_ // Language variables cannot be reduced to a single varref, so they must be skipped
$this->compile_language_tags($text_blocks); // 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);
}
// This will handle the remaining root-level varrefs return $text_blocks;
$text_blocks = preg_replace('#\{(' . self::REGEX_VAR . ')\}#', "<?php echo (isset(\$_rootref['\\1'])) ? \$_rootref['\\1'] : ''; /**/?>", $text_blocks); }
$text_blocks = preg_replace('#\{\$(' . self::REGEX_VAR . ')\}#', "<?php echo (isset(\$_tpldata['DEFINE']['.']['\\1'])) ? \$_tpldata['DEFINE']['.']['\\1'] : ''; /**/?>", $text_blocks);
/**
* 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; return $text_blocks;
} }
@ -343,21 +365,28 @@ class phpbb_template_filter extends php_user_filter
* Handles special language tags L_ and LA_ * Handles special language tags L_ and LA_
* *
* @param string $text_blocks Variable reference in source template * @param string $text_blocks Variable reference in source template
* @return bool Whether a replacement occurred or not
*/ */
private function compile_language_tags(&$text_blocks) 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 // transform vars prefixed by L_ into their language variable pendant if nothing is set within the tpldata array
if (strpos($text_blocks, '{L_') !== false) if (strpos($text_blocks, '{L_') !== false)
{ {
$text_blocks = preg_replace('#\{L_(' . self::REGEX_VAR . ')\}#', "<?php echo ((isset(\$_rootref['L_\\1'])) ? \$_rootref['L_\\1'] : ((isset(\$_lang['\\1'])) ? \$_lang['\\1'] : '{ \\1 }')); /**/?>", $text_blocks); $text_blocks = preg_replace('#\{L_(' . self::REGEX_VAR . ')\}#', "<?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_ // Handle addslashed language variables prefixed with LA_
// If a template variable already exist, it will be used in favor of it... // If a template variable already exist, it will be used in favor of it...
if (strpos($text_blocks, '{LA_') !== false) if (strpos($text_blocks, '{LA_') !== false)
{ {
$text_blocks = preg_replace('#\{LA_(' . self::REGEX_VAR . '+)\}#', "<?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); $text_blocks = preg_replace('#\{LA_(' . self::REGEX_VAR . '+)\}#', "<?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;
} }
/** /**
@ -725,6 +754,18 @@ class phpbb_template_filter extends php_user_filter
*/ */
private function compile_tag_include($tag_args) private function compile_tag_include($tag_args)
{ {
// Process dynamic includes
if ($tag_args[0] == '{')
{
$var = $this->get_varref($tag_args, $is_expr);
// Make sure someone didn't try to include S_FIRST_ROW or similar
if (!$is_expr)
{
return "if (isset($var)) { \$_template->_tpl_include($var); }";
}
}
return "\$_template->_tpl_include('$tag_args');"; return "\$_template->_tpl_include('$tag_args');";
} }
@ -822,17 +863,16 @@ class phpbb_template_filter extends php_user_filter
* *
* @param string $namespace Namespace to access (expects a trailing "." on the namespace) * @param string $namespace Namespace to access (expects a trailing "." on the namespace)
* @param string $varname Variable name to use * @param string $varname Variable name to use
* @param bool $echo If true return an echo statement, otherwise a reference to the internal variable * @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 * @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 * @return string Code to access variable or echo it if $echo is true
*/ */
private function generate_block_varref($namespace, $varname, $echo = true, $defop = false) private function generate_block_varref($namespace, $varname, &$expr, $defop = false)
{ {
// Strip the trailing period. // Strip the trailing period.
$namespace = substr($namespace, 0, -1); $namespace = substr($namespace, 0, -1);
$expr = true; $expr = true;
$isset = false;
// S_ROW_COUNT is deceptive, it returns the current row number now the number of rows // 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 // hence S_ROW_COUNT is deprecated in favour of S_ROW_NUM
@ -868,11 +908,9 @@ class phpbb_template_filter extends php_user_filter
$varref .= "['$varname']"; $varref .= "['$varname']";
$expr = false; $expr = false;
$isset = true;
break; break;
} }
// @todo Test the !$expr more // @todo Test the !$expr more
$varref = ($echo) ? '<?php echo ' . ($isset ? "isset($varref) ? $varref : ''" : $varref) . '; /**/?>' : (($expr || isset($varref)) ? $varref : '');
return $varref; return $varref;
} }

View file

@ -162,6 +162,27 @@ class phpbb_template_template_test extends phpbb_template_template_test_case
array(), array(),
'value', 'value',
), ),
array(
'include_define.html',
array('VARIABLE' => 'value'),
array(),
array(),
'value',
),
array(
'include_loop.html',
array(),
array('loop' => array(array('NESTED_FILE' => 'include_loop1.html')), 'loop.inner' => array(array('NESTED_FILE' => 'include_loop1.html'), array('NESTED_FILE' => 'include_loop2.html'), array('NESTED_FILE' => 'include_loop3.html'))),
array(),
"1\n_1\n_02\n_3",
),
array(
'include_variable.html',
array('FILE' => 'variable.html', 'VARIABLE' => 'value'),
array(),
array(),
'value',
),
array( array(
'loop_vars.html', 'loop_vars.html',
array(), array(),

View file

@ -0,0 +1,2 @@
<!-- DEFINE $DEF = 'variable.html' -->
<!-- INCLUDE {$DEF} -->

View file

@ -0,0 +1,4 @@
<!-- BEGIN loop -->
<!-- INCLUDE {loop.NESTED_FILE} -->
<!-- BEGIN inner -->_<!-- INCLUDE {inner.NESTED_FILE} --><!-- END inner -->
<!-- END loop -->

View file

@ -0,0 +1 @@
1

View file

@ -0,0 +1 @@
02

View file

@ -0,0 +1 @@
3

View file

@ -0,0 +1 @@
<!-- INCLUDE {FILE} -->