From d9991bdaf1aa9685437c4f4c298fa54f0c0f33f0 Mon Sep 17 00:00:00 2001 From: javiexin Date: Wed, 28 Dec 2016 12:37:53 +0100 Subject: [ticket/14943] Fix template loop access by index Allows inserting elements in a loop specified as 'outer[3].inner'. This was coded, but malfunctioning. PHPBB3-14943 --- phpBB/phpbb/template/context.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb/template/context.php') diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index 4ee48205c8..8bf6c10e2d 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -365,15 +365,15 @@ class context if ($mode == 'insert') { // Make sure we are not exceeding the last iteration - if ($key >= sizeof($this->tpldata[$blockname])) + if ($key >= sizeof($block)) { - $key = sizeof($this->tpldata[$blockname]); - unset($this->tpldata[$blockname][($key - 1)]['S_LAST_ROW']); + $key = sizeof($block); + unset($block[($key - 1)]['S_LAST_ROW']); $vararray['S_LAST_ROW'] = true; } else if ($key === 0) { - unset($this->tpldata[$blockname][0]['S_FIRST_ROW']); + unset($block[0]['S_FIRST_ROW']); $vararray['S_FIRST_ROW'] = true; } -- cgit v1.2.1 From cff57f9076dd160b2185895f7298d4acbc5b5bb3 Mon Sep 17 00:00:00 2001 From: javiexin Date: Wed, 28 Dec 2016 12:55:26 +0100 Subject: [ticket/14944] Add possibility to search for template loop indexes by key Adds a new function to the template interface, and implements it in the context class. The function returns the ordinal index for a specified key, with the same structure that the key for alter_block_array. Reuses same code. PHPBB3-14944 --- phpBB/phpbb/template/context.php | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'phpBB/phpbb/template/context.php') diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index 4ee48205c8..e390c5a677 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -263,6 +263,77 @@ class context return true; } + /** + * Find the index for a specified key in the innermost specified block + * + * @param string $blockname the blockname, for example 'loop' + * @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 search for] + * + * If key is false the position is set to 0 + * If key is true the position is set to the last entry + * + * @return mixed false if not found, index position otherwise; be sure to test with === + */ + public function find_key_index($blockname, $key = false) + { + // For nested block, $blockcount > 0, for top-level block, $blockcount == 0 + $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 + + // Change key to zero (change first position) if false and to last position if true + if ($key === false || $key === true) + { + return ($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); + foreach ($block as $i => $val_ary) + { + if ($val_ary[$search_key] === $search_value) + { + return $i; + } + } + } + + return false; + } + /** * Change already assigned key variable pair (one-dimensional - single loop entry) * -- cgit v1.2.1 From c656bd60ef99218a710882b6f640fea099e9c6e2 Mon Sep 17 00:00:00 2001 From: javiexin Date: Fri, 30 Dec 2016 18:03:09 +0100 Subject: [ticket/14944] Add possibility to search for template loop indexes by key Adds a new function to the template interface, and implements it in the context class. The function returns the ordinal index for a specified key, with the same structure that the key for alter_block_array. Reuses same code. Remove unneeded references, do nothing for int keys. PHPBB3-14944 --- phpBB/phpbb/template/context.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb/template/context.php') diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index e390c5a677..1617ca3d19 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -284,7 +284,7 @@ class context $blocks = explode('.', $blockname); $blockcount = sizeof($blocks) - 1; - $block = &$this->tpldata; + $block = $this->tpldata; for ($i = 0; $i < $blockcount; $i++) { if (($pos = strpos($blocks[$i], '[')) !== false) @@ -305,11 +305,11 @@ class context $name = $blocks[$i]; $index = sizeof($block[$name]) - 1; } - $block = &$block[$name]; - $block = &$block[$index]; + $block = $block[$name]; + $block = $block[$index]; } - $block = &$block[$blocks[$i]]; // Traverse the last block + $block = $block[$blocks[$i]]; // Traverse the last block // Change key to zero (change first position) if false and to last position if true if ($key === false || $key === true) @@ -331,7 +331,7 @@ class context } } - return false; + return is_int($key) ? $key : false; } /** -- cgit v1.2.1 From 45ea013b111547ef684cc7c64dd91a6217935ab1 Mon Sep 17 00:00:00 2001 From: javiexin Date: Sun, 1 Jan 2017 21:22:29 +0100 Subject: [ticket/14943] Fix template loop access by index Allows inserting elements in a loop specified as 'outer[3].inner'. This was coded, but malfunctioning. Name incorrectly set on insert. PHPBB3-14943 --- phpBB/phpbb/template/context.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb/template/context.php') diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index 8bf6c10e2d..f0bc4c859a 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -325,11 +325,13 @@ class context } $block = &$block[$blocks[$i]]; // Traverse the last block + $name = $blocks[$i]; } else { // Top-level block. $block = &$this->tpldata[$blockname]; + $name = $blockname; } // Change key to zero (change first position) if false and to last position if true @@ -378,7 +380,7 @@ class context } // Assign S_BLOCK_NAME - $vararray['S_BLOCK_NAME'] = $blockname; + $vararray['S_BLOCK_NAME'] = $name; // Re-position template blocks for ($i = sizeof($block); $i > $key; $i--) -- cgit v1.2.1 From 20c03cccdde2302412d1e14adda370e7eb57b8e8 Mon Sep 17 00:00:00 2001 From: javiexin Date: Sun, 8 Jan 2017 00:00:47 +0100 Subject: [ticket/14944] Add possibility to search for template loop indexes by key Adds a new function to the template interface, and implements it in the context class. The function returns the ordinal index for a specified key, with the same structure that the key for alter_block_array. Reuses same code. Remove unneeded references, do nothing for int keys. Check out of bounds or wrong blockname errors. Added tests. PHPBB3-14944 --- phpBB/phpbb/template/context.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb/template/context.php') diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index 1617ca3d19..8bfbd73f1a 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -305,16 +305,28 @@ class context $name = $blocks[$i]; $index = sizeof($block[$name]) - 1; } + if (!isset($block[$name])) + { + return false; + } $block = $block[$name]; + if (!isset($block[$index])) + { + return false; + } $block = $block[$index]; } + if (!isset($block[$blocks[$i]])) + { + return false; + } $block = $block[$blocks[$i]]; // Traverse the last block // Change key to zero (change first position) if false and to last position if true if ($key === false || $key === true) { - return ($key === false) ? 0 : sizeof($block); + return ($key === false) ? 0 : sizeof($block) - 1; } // Get correct position if array given @@ -331,7 +343,7 @@ class context } } - return is_int($key) ? $key : false; + return (is_int($key) && ((0 <= $key) && ($key < sizeof($block)))) ? $key : false; } /** -- cgit v1.2.1 From d2ad751851c955c19d1688cbe511925489212121 Mon Sep 17 00:00:00 2001 From: javiexin Date: Thu, 12 Jan 2017 21:25:39 +0100 Subject: [ticket/14943] Fix template loop access by index Allows inserting elements in a loop specified as 'outer[3].inner'. This was coded, but malfunctioning. Name incorrectly set on insert. If block was empty, the insertion process should create it. Checking for out of bounds indexes. PHPBB3-14943 --- phpBB/phpbb/template/context.php | 69 +++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 30 deletions(-) (limited to 'phpBB/phpbb/template/context.php') diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index f0bc4c859a..4235a8543e 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -293,47 +293,49 @@ class context public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') { $this->num_rows_is_set = false; - if (strpos($blockname, '.') !== false) - { - // Nested block. - $blocks = explode('.', $blockname); - $blockcount = sizeof($blocks) - 1; - $block = &$this->tpldata; - for ($i = 0; $i < $blockcount; $i++) + // For nested block, $blockcount > 0, for top-level block, $blockcount == 0 + $blocks = explode('.', $blockname); + $blockcount = sizeof($blocks) - 1; + + $block = &$this->tpldata; + for ($i = 0; $i < $blockcount; $i++) + { + if (($pos = strpos($blocks[$i], '[')) !== false) { - if (($pos = strpos($blocks[$i], '[')) !== false) + $name = substr($blocks[$i], 0, $pos); + + if (strpos($blocks[$i], '[]') === $pos) { - $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); - } + $index = sizeof($block[$name]) - 1; } else { - $name = $blocks[$i]; - $index = sizeof($block[$name]) - 1; + $index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1); } - $block = &$block[$name]; - $block = &$block[$index]; } - - $block = &$block[$blocks[$i]]; // Traverse the last block - $name = $blocks[$i]; + else + { + $name = $blocks[$i]; + $index = sizeof($block[$name]) - 1; + } + $block = &$block[$name]; + $block = &$block[$index]; } - else + $name = $blocks[$i]; + + // If last block does not exist and we are inserting, and not searching for key, we create it empty; otherwise, nothing to do + if (!isset($block[$name])) { - // Top-level block. - $block = &$this->tpldata[$blockname]; - $name = $blockname; + if ($mode != 'insert' || is_array($key)) + { + return false; + } + $block[$name] = array(); } + $block = &$block[$name]; // Now we can traverse the last block + // Change key to zero (change first position) if false and to last position if true if ($key === false || $key === true) { @@ -373,8 +375,9 @@ class context unset($block[($key - 1)]['S_LAST_ROW']); $vararray['S_LAST_ROW'] = true; } - else if ($key === 0) + if ($key <= 0) { + $key = 0; unset($block[0]['S_FIRST_ROW']); $vararray['S_FIRST_ROW'] = true; } @@ -400,6 +403,12 @@ class context // Which block to change? if ($mode == 'change') { + // If key is out of bounds, do not change anything + if ($key > sizeof($block) || $key < 0) + { + return false; + } + if ($key == sizeof($block)) { $key--; -- cgit v1.2.1 From 849fd9df7d9b2e449801e14ef54584fc8e063d43 Mon Sep 17 00:00:00 2001 From: javiexin Date: Sat, 28 Jan 2017 21:34:08 +0100 Subject: [ticket/14944] Add possibility to search for template loop indexes by key Adds a new function to the template interface, and implements it in the context class. The function returns the ordinal index for a specified key, with the same structure that the key for alter_block_array. Reuses same code. Remove unneeded references, do nothing for int keys. Check out of bounds or wrong blockname errors. Added tests. Remove default parameter value. PHPBB3-14944 --- phpBB/phpbb/template/context.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb/template/context.php') diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index 8bfbd73f1a..e70d0574be 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -278,7 +278,7 @@ class context * * @return mixed false if not found, index position otherwise; be sure to test with === */ - public function find_key_index($blockname, $key = false) + public function find_key_index($blockname, $key) { // For nested block, $blockcount > 0, for top-level block, $blockcount == 0 $blocks = explode('.', $blockname); -- cgit v1.2.1