diff options
author | Andrey Andreev <narf@devilix.net> | 2014-01-06 13:38:00 +0100 |
---|---|---|
committer | Andrey Andreev <narf@devilix.net> | 2014-01-06 13:38:00 +0100 |
commit | a9c7d18dc4ba53507d6e606221f06aa3fafeaa8e (patch) | |
tree | d48c6a9ee35dbedc484740ef9d1850a8f9677627 | |
parent | 45549a2919892e31782fc4381d7db8c6f3293bcb (diff) |
Fix #2237: Parser library failed if the same tag pair is used more than once within a template
(manually applying PR #2238 + updated unit tests)
-rw-r--r-- | system/libraries/Parser.php | 30 | ||||
-rw-r--r-- | tests/codeigniter/libraries/Parser_test.php | 4 | ||||
-rw-r--r-- | user_guide_src/source/changelog.rst | 1 |
3 files changed, 22 insertions, 13 deletions
diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php index c1f1ad73b..399131cdd 100644 --- a/system/libraries/Parser.php +++ b/system/libraries/Parser.php @@ -187,26 +187,34 @@ class CI_Parser { */ protected function _parse_pair($variable, $data, $string) { - if (FALSE === ($match = $this->_match_pair($string, $variable))) + if (FALSE === ($matches = $this->_match_pair($string, $variable))) { return $string; } $str = ''; - foreach ($data as $row) + $search = $replace = array(); + foreach ($matches as $match) { - $temp = $match[1]; - foreach ($row as $key => $val) + $str = ''; + foreach ($data as $row) { - $temp = is_array($val) + $temp = $match[1]; + foreach ($row as $key => $val) + { + $temp = is_array($val) ? $this->_parse_pair($key, $val, $temp) : $this->_parse_single($key, $val, $temp); + } + + $str .= $temp; } - $str .= $temp; + $search[] = $match[0]; + $replace[] = $str; } - return str_replace($match[0], $str, $string); + return str_replace($search, $replace, $string); } // -------------------------------------------------------------------- @@ -214,14 +222,14 @@ class CI_Parser { /** * Matches a variable pair * - * @param string - * @param string + * @param string $string + * @param string $variable * @return mixed */ protected function _match_pair($string, $variable) { - return preg_match('|'.preg_quote($this->l_delim).$variable.preg_quote($this->r_delim).'(.+?)'.preg_quote($this->l_delim).'/'.$variable.preg_quote($this->r_delim).'|s', - $string, $match) + return preg_match_all('|'.preg_quote($this->l_delim).$variable.preg_quote($this->r_delim).'(.+?)'.preg_quote($this->l_delim).'/'.$variable.preg_quote($this->r_delim).'|s', + $string, $match, PREG_SET_ORDER) ? $match : FALSE; } diff --git a/tests/codeigniter/libraries/Parser_test.php b/tests/codeigniter/libraries/Parser_test.php index 394c22692..6e5c192dd 100644 --- a/tests/codeigniter/libraries/Parser_test.php +++ b/tests/codeigniter/libraries/Parser_test.php @@ -76,9 +76,9 @@ class Parser_test extends CI_TestCase { ) ); - $template = "{title}\n{powers}{invisibility}\n{flying}{/powers}"; + $template = "{title}\n{powers}{invisibility}\n{flying}{/powers}\nsecond:{powers} {invisibility} {flying}{/powers}"; - $this->assertEquals("Super Heroes\nyes\nno", $this->parser->parse_string($template, $data, TRUE)); + $this->assertEquals("Super Heroes\nyes\nno\nsecond: yes no", $this->parser->parse_string($template, $data, TRUE)); } // -------------------------------------------------------------------- diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index 7cc27eb5a..6d0ceb6c3 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -631,6 +631,7 @@ Bug fixes for 3.0 - Fixed a bug - Redis :doc:`Caching <libraries/caching>` driver didn't handle connection failures properly. - Fixed a bug (#2756) - :doc:`Database Class <database/index>` executed the MySQL-specific `SET SESSION sql_mode` query for all drivers when the 'stricton' option is set. - Fixed a bug (#2579) - :doc:`Query Builder <database/query_builder>`s "no escape" functionality didn't work properly with query cache. +- Fixed a bug (#2237) - :doc:`Parser Library <libraries/parser>` failed if the same tag pair is used more than once within a template. Version 2.1.4 ============= |