From c95f0c793543e4af68df133a09d0db5af3b4a822 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Tue, 25 Nov 2008 00:31:32 +0000 Subject: [PATCH] - Add template variable S_BLOCK_NAME - Modify template::alter_block_array() so it supports modification of nested blocks - Add (incomplete) tests for template::alter_block_array() git-svn-id: file:///svn/phpbb/trunk@9116 89ea8834-ac86-4346-8a33-228a782c2dd0 --- phpBB/includes/functions_template.php | 15 +- phpBB/includes/template.php | 52 ++++- tests/template/template.php | 257 ++++++++++++++++++++++ tests/template/templates/loop_nested.html | 8 + 4 files changed, 322 insertions(+), 10 deletions(-) create mode 100644 tests/template/templates/loop_nested.html diff --git a/phpBB/includes/functions_template.php b/phpBB/includes/functions_template.php index c8c79ab5e4..71de53b4c4 100644 --- a/phpBB/includes/functions_template.php +++ b/phpBB/includes/functions_template.php @@ -458,6 +458,10 @@ class template_filter extends php_user_filter $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] . '\']'; break; @@ -637,6 +641,8 @@ class template_filter extends php_user_filter // Strip the trailing period. $namespace = substr($namespace, 0, -1); + $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) @@ -658,6 +664,10 @@ class template_filter extends php_user_filter $varref = "(\$_${namespace}_i == \$_${namespace}_count - 1)"; break; + case 'S_BLOCK_NAME': + $varref = "'$namespace'"; + break; + default: // Get a reference to the data block for this namespace. $varref = $this->generate_block_data_ref($namespace, true, $defop); @@ -665,9 +675,12 @@ class template_filter extends php_user_filter // Append the variable reference. $varref .= "['$varname']"; + + $expr = false; break; } - $varref = ($echo) ? "" : ((isset($varref)) ? $varref : ''); + // @todo Test the !$expr more + $varref = ($echo) ? "" : (($expr || isset($varref)) ? $varref : ''); return $varref; } diff --git a/phpBB/includes/template.php b/phpBB/includes/template.php index 953cc984c0..a49fd75eb3 100644 --- a/phpBB/includes/template.php +++ b/phpBB/includes/template.php @@ -386,14 +386,47 @@ class template { if (strpos($blockname, '.') !== false) { - // Nested blocks are not supported - return 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($this->_tpldata[$blockname]); + $key = ($key === false) ? 0 : sizeof($block); } // Get correct position if array given @@ -403,7 +436,7 @@ class template list($search_key, $search_value) = @each($key); $key = NULL; - foreach ($this->_tpldata[$blockname] as $i => $val_ary) + foreach ($block as $i => $val_ary) { if ($val_ary[$search_key] === $search_value) { @@ -423,13 +456,13 @@ class template if ($mode == 'insert') { // Re-position template blocks - for ($i = sizeof($this->_tpldata[$blockname]); $i > $key; $i--) + for ($i = sizeof($block); $i > $key; $i--) { - $this->_tpldata[$blockname][$i] = $this->_tpldata[$blockname][$i-1]; + $block[$i] = $block[$i-1]; } // Insert vararray at given position - $this->_tpldata[$blockname][$key] = $vararray; + $block[$key] = $vararray; return true; } @@ -437,12 +470,13 @@ class template // Which block to change? if ($mode == 'change') { - if ($key == sizeof($this->_tpldata[$blockname])) + if ($key == sizeof($block)) { $key--; } - $this->_tpldata[$blockname][$key] = array_merge($this->_tpldata[$blockname][$key], $vararray); + $block[$key] = array_merge($block[$key], $vararray); + return true; } diff --git a/tests/template/template.php b/tests/template/template.php index 9558ea09f9..72905c9f1a 100644 --- a/tests/template/template.php +++ b/tests/template/template.php @@ -22,6 +22,7 @@ class phpbb_template_template_test extends phpbb_test_case { private $template; + // Keep the contents of the cache for debugging? const PRESERVE_CACHE = true; private function display($handle) @@ -359,5 +360,261 @@ class phpbb_template_template_test extends phpbb_test_case unset($config['tpl_allow_php']); } + + public static function alter_block_array_data() + { + return array( + array( + 'outer', + array('VARIABLE' => 'before'), + false, + 'insert', + << 'after'), + true, + 'insert', + << 'pos #1'), + 1, + 'insert', + << 'pos #1'), + 0, + 'change', + << 'before'), + false, + 'insert', + << 'after'), + true, + 'insert', + << 'pos #1'), + 1, + 'insert', + << 'before'), + false, + 'insert', + << 'before'), + false, + 'insert', + << 'before'), + false, + 'insert', + <<template->set_filenames(array('test' => 'loop_nested.html')); + + // @todo Change this + $this->template->assign_block_vars('outer', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer.middle', array()); + + $this->assertEquals("outer - 0/3\nmiddle - 0/2\nmiddle - 1/2\nouter - 1/3\nmiddle - 0/3\nmiddle - 1/3\nmiddle - 2/3\nouter - 2/3\nmiddle - 0/2\nmiddle - 1/2", $this->display('test'), 'Ensuring template is built correctly before modification'); + + $this->template->alter_block_array($alter_block, $vararray, $key, $mode); + $this->assertEquals($expect, $this->display('test'), $description); + } } ?> \ No newline at end of file diff --git a/tests/template/templates/loop_nested.html b/tests/template/templates/loop_nested.html new file mode 100644 index 0000000000..571df97b4c --- /dev/null +++ b/tests/template/templates/loop_nested.html @@ -0,0 +1,8 @@ + + {outer.S_BLOCK_NAME} - {outer.S_ROW_NUM}/{outer.S_NUM_ROWS} - {outer.VARIABLE} + + + {middle.S_BLOCK_NAME} - {middle.S_ROW_NUM}/{middle.S_NUM_ROWS} - {middle.VARIABLE} + + +