From 1726bad39658195c4bd8642e16c554858fe573b3 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Thu, 11 Aug 2011 13:26:06 -0430 Subject: [PATCH] Adding ability to Set class to iterate on ArrayObjects, or any object implementing ArrayAccess and Traversable --- lib/Cake/Test/Case/Model/DbAclTest.php | 4 ++-- lib/Cake/Test/Case/Utility/SetTest.php | 19 +++++++++++++++++++ lib/Cake/Utility/Set.php | 13 ++++++++----- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/lib/Cake/Test/Case/Model/DbAclTest.php b/lib/Cake/Test/Case/Model/DbAclTest.php index 68e813fc029..237cdaac3df 100644 --- a/lib/Cake/Test/Case/Model/DbAclTest.php +++ b/lib/Cake/Test/Case/Model/DbAclTest.php @@ -299,10 +299,10 @@ public function testNode() { $this->assertEqual($expected, $result); $result = Set::extract($Aco->node('Controller2/action3'), '{n}.DbAcoTest.id'); - $this->assertFalse($result); + $this->assertNull($result); $result = Set::extract($Aco->node('Controller2/action3/record5'), '{n}.DbAcoTest.id'); - $this->assertFalse($result); + $this->assertNull($result); $result = $Aco->node(''); $this->assertEqual($result, null); diff --git a/lib/Cake/Test/Case/Utility/SetTest.php b/lib/Cake/Test/Case/Utility/SetTest.php index a792917bf10..a0f0042cc2d 100644 --- a/lib/Cake/Test/Case/Utility/SetTest.php +++ b/lib/Cake/Test/Case/Utility/SetTest.php @@ -1594,6 +1594,25 @@ public function testClassicExtract() { $result = Set::extract($a, 'articles.{n}.Article.title'); $expected = array('Article 1', 'Article 2', 'Article 3'); $this->assertEquals($expected, $result); + + $a = new ArrayObject(); + $a['articles'] = array( + array('Article' => array('id' => 1, 'title' => 'Article 1')), + array('Article' => array('id' => 2, 'title' => 'Article 2')), + array('Article' => array('id' => 3, 'title' => 'Article 3')) + ); + + $result = Set::extract($a, 'articles.{n}.Article.id'); + $expected = array(1, 2, 3); + $this->assertEquals($expected, $result); + + $result = Set::extract($a, 'articles.{n}.Article.title'); + $expected = array('Article 1', 'Article 2', 'Article 3'); + $this->assertEquals($expected, $result); + + $result = Set::extract($a, 'articles.0.Article.title'); + $expected = 'Article 1'; + $this->assertEquals($expected, $result); } /** diff --git a/lib/Cake/Utility/Set.php b/lib/Cake/Utility/Set.php index 4efd4356395..b93b4e18f87 100644 --- a/lib/Cake/Utility/Set.php +++ b/lib/Cake/Utility/Set.php @@ -565,12 +565,13 @@ public static function classicExtract($data, $path = null) { return $data; } if (is_object($data)) { - $data = get_object_vars($data); + if (!($data instanceof ArrayAccess || $data instanceof Traversable)) { + $data = get_object_vars($data); + } } - if (!is_array($data)) { - return $data; + if (empty($data)) { + return null; } - if (is_string($path) && strpos($path, '{') !== false) { $path = String::tokenize($path, '.', '{', '}'); } elseif (is_string($path)) { @@ -877,7 +878,9 @@ public static function combine($data, $path1 = null, $path2 = null, $groupPath = } if (is_object($data)) { - $data = get_object_vars($data); + if (!($data instanceof ArrayAccess || $data instanceof Traversable)) { + $data = get_object_vars($data); + } } if (is_array($path1)) {