From db96a250d1b37534d9124dc99f8009274c008b50 Mon Sep 17 00:00:00 2001 From: the_undefined Date: Thu, 17 Apr 2008 15:48:55 +0000 Subject: [PATCH] Fixed :first / :last selector issues in Set::matches Refactored condition filtering to respect context altering conditions in Set::extract Fixed some bad test cases git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6679 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/libs/set.php | 30 ++++++++++++++++++++++-------- cake/tests/cases/libs/set.test.php | 13 ++++++++----- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/cake/libs/set.php b/cake/libs/set.php index ac715132a..608183871 100644 --- a/cake/libs/set.php +++ b/cake/libs/set.php @@ -444,18 +444,14 @@ class Set extends Object { if (!is_array($items) || !isset($items[0])) { $items = array($items); } - foreach ($items as $item) { - if ($conditions && !Set::matches($conditions, $item, $i, $contextsCount)) { - continue; - } $matches[] = array( 'trace' => am($context['trace'], $context['key']), 'key' => $token, 'item' => $item, ); } - } elseif (($key === $token || (ctype_digit($token) && $key == $token) || $token === '.') && (!$conditions || Set::matches($conditions, $context['item'], $i, $contextsCount))) { + } elseif (($key === $token || (ctype_digit($token) && $key == $token) || $token === '.')) { $matches[] = array( 'trace' => am($context['trace'], $key), 'key' => $key, @@ -463,10 +459,22 @@ class Set extends Object { ); } } + if ($conditions) { + foreach ($conditions as $condition) { + $filtered = array(); + $length = count($matches); + foreach ($matches as $i => $match) { + if (Set::matches(array($condition), $match['item'], $i+1, $length)) { + $filtered[] = $match; + } + } + $matches = $filtered; + } + } + $contexts = $matches; if (empty($tokens)) { break; } - $contexts = $matches; } while(1); $r = array(); @@ -497,9 +505,15 @@ class Set extends Object { } foreach ($conditions as $condition) { if ($condition == ':last') { - return $i == ($length-1); + if ($i != $length) { + return false; + } + continue; } elseif ($condition == ':first') { - return $i == 1; + if ($i != 1) { + return false; + } + continue; } if (!preg_match('/(.+?)([><])(.+)/', $condition, $match)) { if (ctype_digit($condition)) { diff --git a/cake/tests/cases/libs/set.test.php b/cake/tests/cases/libs/set.test.php index 03c89f8e3..d482e028a 100644 --- a/cake/tests/cases/libs/set.test.php +++ b/cake/tests/cases/libs/set.test.php @@ -485,7 +485,7 @@ class SetTest extends UnitTestCase { ), array( 'id' => 5, - 'user_id' => 3, + 'user_id' => 23, 'article_id' => 2, 'text' => 'Comment 5', ), @@ -519,12 +519,12 @@ class SetTest extends UnitTestCase { $r = Set::extract($common, '/Comment/2'); $this->assertEqual($r, $expected); - $expected = array($common[0]['Comment'][1]); - $r = Set::extract($common, '/Comment[1]/.[id=2]'); + $expected = array($common[0]['Comment'][0]); + $r = Set::extract($common, '/Comment[1]/.[id=1]'); $this->assertEqual($r, $expected); - $expected = array($common[0]['Comment'][1]); - $r = Set::extract($common, '/Comment[1]/.[2]'); + $expected = array($common[1]['Comment'][1]); + $r = Set::extract($common, '/1/Comment/.[2]'); $this->assertEqual($r, $expected); $expected = array(); @@ -539,6 +539,9 @@ class SetTest extends UnitTestCase { $r = Set::extract('/Comment/id[:first]', $common); $this->assertEqual($r, $expected); + $expected = array(3); + $r = Set::extract('/Article[:last]/id', $common); + $this->assertEqual($r, $expected); } /** * undocumented function