From b1b93709f04f2b78a385fbc4e33b044c3a05f4ed Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Sat, 17 Aug 2013 14:32:55 +0200 Subject: [PATCH] Updating find('threaded') to not return ArrayObject anymore and to account for top parents that are not null or zero --- lib/Cake/ORM/Query.php | 10 ++--- lib/Cake/ORM/Table.php | 29 +++++++++----- lib/Cake/Test/TestCase/ORM/TableTest.php | 48 ++++++++++++------------ 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/lib/Cake/ORM/Query.php b/lib/Cake/ORM/Query.php index 3cba346f51b..21ff9b7c144 100644 --- a/lib/Cake/ORM/Query.php +++ b/lib/Cake/ORM/Query.php @@ -533,17 +533,17 @@ public function mapReduce(callable $mapper, callable $reducer = null) { } protected function _applyFormatters($result) { - foreach ($this->_formatters as $formatter) { - $result = new ResultSetDecorator($result, $formatter); - } - foreach ($this->_mapReduce as $mappers) { $result = new MapReduce($result, $mappers); } if (!empty($this->_mapReduce)) { $result = new ResultSetDecorator($result); - } + } + + foreach ($this->_formatters as $formatter) { + $result = new ResultSetDecorator($result, $formatter); + } return $result; } diff --git a/lib/Cake/ORM/Table.php b/lib/Cake/ORM/Table.php index 391c6baedd0..1066e081871 100644 --- a/lib/Cake/ORM/Table.php +++ b/lib/Cake/ORM/Table.php @@ -552,19 +552,28 @@ public function findList(Query $query, array $options = []) { } public function findThreaded(Query $query, array $options = []) { - $parents = new \ArrayObject; - $mapper = function($key, $row, $mr) use ($parents) { - $parents[$row['id']] = new \ArrayObject($row); - if (empty($row['parent_id'])) { - return $mr->emit($parents[$row['id']]); - } - $mr->emitIntermediate($row['parent_id'], $parents[$row['id']]); + $parents = []; + $mapper = function($key, $row, $mr) use (&$parents) { + $parents[$row['id']] = &$row; + $mr->emitIntermediate($row['parent_id'], $row['id']); }; - $reducer = function($key, $values, $mr) use ($parents) { - $parents[$key]['children'] = $values; + $reducer = function($key, $values, $mr) use (&$parents) { + if (empty($key) || !isset($parents[$key])) { + foreach ($values as $id) { + $parents[$id] = new \ArrayObject($parents[$id]); + $mr->emit($parents[$id]); + } + return; + } + foreach ($values as $id) { + $parents[$key]['children'][] =& $parents[$id]; + } }; - return $query->mapReduce($mapper, $reducer); + + return $query->mapReduce($mapper, $reducer)->formatResults(function($row) { + return $row->getArrayCopy(); + }); } /** diff --git a/lib/Cake/Test/TestCase/ORM/TableTest.php b/lib/Cake/Test/TestCase/ORM/TableTest.php index a74d0d441a4..b937fa682f2 100644 --- a/lib/Cake/Test/TestCase/ORM/TableTest.php +++ b/lib/Cake/Test/TestCase/ORM/TableTest.php @@ -541,54 +541,54 @@ public function testFindList() { public function testFindThreaded() { $table = new Table(['table' => 'categories', 'connection' => $this->connection]); - $expected = array( - new \ArrayObject(array( + $expected = [ + [ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1', - 'children' => array( - new \ArrayObject(array( + 'children' => [ + [ 'id' => 2, 'parent_id' => 1, 'name' => 'Category 1.1', - 'children' => array( - new \ArrayObject(array( + 'children' => [ + [ 'id' => 7, 'parent_id' => 2, 'name' => 'Category 1.1.1', - )), - new \ArrayObject(array( + ], + [ 'id' => 8, 'parent_id' => '2', 'name' => 'Category 1.1.2', - )) - ), - )), - new \ArrayObject(array( + ] + ], + ], + [ 'id' => 3, 'parent_id' => '1', 'name' => 'Category 1.2', - )), - ) - )), - new \ArrayObject(array( + ], + ] + ], + [ 'id' => 4, 'parent_id' => 0, 'name' => 'Category 2', - )), - new \ArrayObject(array( + ], + [ 'id' => 5, 'parent_id' => 0, 'name' => 'Category 3', - 'children' => array( - new \ArrayObject(array( + 'children' => [ + [ 'id' => '6', 'parent_id' => '5', 'name' => 'Category 3.1', - )) - ) - )) - ); + ] + ] + ] + ]; $results = $table->find('threaded') ->select(['id', 'parent_id', 'name']) ->toArray();