diff --git a/lib/Cake/Test/Case/Utility/SetTest.php b/lib/Cake/Test/Case/Utility/SetTest.php index 663d60463..e1cb1dde1 100644 --- a/lib/Cake/Test/Case/Utility/SetTest.php +++ b/lib/Cake/Test/Case/Utility/SetTest.php @@ -3129,6 +3129,52 @@ class SetTest extends CakeTestCase { $this->assertEquals($expected, $result); } +/** + * Tests Set::expand + * + * @return void + */ + public function testExpand() { + $data = array('My', 'Array', 'To', 'Flatten'); + $flat = Set::flatten($data); + $result = Set::expand($flat); + $this->assertEqual($data, $result); + + $data = array( + '0.Post.id' => '1', '0.Post.author_id' => '1', '0.Post.title' => 'First Post', '0.Author.id' => '1', + '0.Author.user' => 'nate', '0.Author.password' => 'foo', '1.Post.id' => '2', '1.Post.author_id' => '3', + '1.Post.title' => 'Second Post', '1.Post.body' => 'Second Post Body', '1.Author.id' => '3', + '1.Author.user' => 'larry', '1.Author.password' => null + ); + $result = Set::expand($data); + $expected = array( + array( + 'Post' => array('id' => '1', 'author_id' => '1', 'title' => 'First Post'), + 'Author' => array('id' => '1', 'user' => 'nate', 'password' => 'foo'), + ), + array( + 'Post' => array('id' => '2', 'author_id' => '3', 'title' => 'Second Post', 'body' => 'Second Post Body'), + 'Author' => array('id' => '3', 'user' => 'larry', 'password' => null), + ) + ); + $this->assertEqual($result, $expected); + + $data = array( + '0/Post/id' => 1, + '0/Post/name' => 'test post' + ); + $result = Set::expand($data, '/'); + $expected = array( + array( + 'Post' => array( + 'id' => 1, + 'name' => 'test post' + ) + ) + ); + $this->assertEqual($result, $expected); + } + /** * test normalization * diff --git a/lib/Cake/Utility/Set.php b/lib/Cake/Utility/Set.php index 181f1b088..ad0bc277d 100644 --- a/lib/Cake/Utility/Set.php +++ b/lib/Cake/Utility/Set.php @@ -1036,6 +1036,36 @@ class Set { return $result; } +/** + * Expand/unflattens an string to an array + * + * For example, unflattens an array that was collapsed with `Set::flatten()` + * into a multi-dimensional array. So, `array('0.Foo.Bar' => 'Far')` becomes + * `array(array('Foo' => array('Bar' => 'Far')))`. + * + * @param array $data Flattened array + * @param string $separator The delimiter used + * @return array + */ + public static function expand($data, $separator = '.') { + $result = array(); + foreach ($data as $flat => $value) { + $keys = explode($separator, $flat); + $keys = array_reverse($keys); + $child = array( + $keys[0] => $value + ); + array_shift($keys); + foreach ($keys as $k) { + $child = array( + $k => $child + ); + } + $result = Set::merge($result, $child); + } + return $result; + } + /** * Flattens an array for sorting *