From cbfa938303ef4dfb76840a0c86aec2dddb48ad3e Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 24 Jan 2012 07:27:21 -0500 Subject: [PATCH] Fix muliple attribute conditions. --- lib/Cake/Test/Case/Utility/Set2Test.php | 21 +++++++++-- lib/Cake/Utility/Set2.php | 46 ++++++++++++++----------- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/lib/Cake/Test/Case/Utility/Set2Test.php b/lib/Cake/Test/Case/Utility/Set2Test.php index 22e9e43bc..505cf588b 100644 --- a/lib/Cake/Test/Case/Utility/Set2Test.php +++ b/lib/Cake/Test/Case/Utility/Set2Test.php @@ -706,11 +706,11 @@ class Set2Test extends CakeTestCase { $data = self::articleData(); $result = Set2::extract($data, '{n}.Article[published]'); - $expected = array($data['1']['Article']); + $expected = array($data[1]['Article']); $this->assertEquals($expected, $result); $result = Set2::extract($data, '{n}.Article[id][published]'); - $expected = array($data['1']['Article']); + $expected = array($data[1]['Article']); $this->assertEquals($expected, $result); } @@ -766,4 +766,21 @@ class Set2Test extends CakeTestCase { $this->assertEquals(2, $expected[0]['user_id']); } +/** + * Test multiple attributes with conditions. + * + * @return void + */ + public function testExtractAttributeMultiple() { + $data = self::articleData(); + + $result = Set2::extract($data, '{n}.Comment.{n}[user_id > 2][id=1]'); + $this->assertEmpty($result); + + $result = Set2::extract($data, '{n}.Comment.{n}[user_id > 2][id=2]'); + $expected = array($data[0]['Comment'][1]); + $this->assertEquals($expected, $result); + $this->assertEquals(4, $expected[0]['user_id']); + } + } diff --git a/lib/Cake/Utility/Set2.php b/lib/Cake/Utility/Set2.php index 487dfb3ab..57230f3e4 100644 --- a/lib/Cake/Utility/Set2.php +++ b/lib/Cake/Utility/Set2.php @@ -193,43 +193,49 @@ class Set2 { */ protected static function _matches(array $data, $selector) { preg_match_all( - '/(\[ (?.+?) (?: \s* (?(?:[><])) \s* (?.*) )? \])+/x', + '/(\[ (?[^=>[><]) \s* (?[^\]]+) )? \])/x', $selector, $conditions, PREG_SET_ORDER ); - foreach ($conditions as $cond) { + $ok = true; + while ($ok) { + if (empty($conditions)) { + break; + } + $cond = array_shift($conditions); $attr = $cond['attr']; $op = isset($cond['op']) ? $cond['op'] : null; $val = isset($cond['val']) ? $cond['val'] : null; // Presence test. - if (empty($op) && empty($val)) { - return isset($data[$attr]); + if (empty($op) && empty($val) && !isset($data[$attr])) { + $ok = false; } // Empty attribute = fail. if (!isset($data[$attr])) { + $ok = false; + } + + $prop = isset($data[$attr]) ? $data[$attr] : null; + + if ( + ($op === '=' && $prop != $val) || + ($op === '!=' && $prop == $val) || + ($op === '>' && $prop <= $val) || + ($op === '<' && $prop >= $val) || + ($op === '>=' && $prop < $val) || + ($op === '<=' && $prop > $val) + ) { + $ok = false; + } + if (!$ok) { return false; } - $prop = $data[$attr]; - - if ($op === '=') { - return $prop == $val; - } elseif ($op === '!=') { - return $prop != $val; - } elseif ($op === '>') { - return $prop > $val; - } elseif ($op === '<') { - return $prop < $val; - } elseif ($op === '>=') { - return $prop >= $val; - } elseif ($op === '<=') { - return $prop <= $val; - } } - return false; + return true; } public static function insert(array $data, $path, $values = null) {