From c59467491f6bb7b3f0c9fdc8b10596010c63d00d Mon Sep 17 00:00:00 2001 From: shaddowgh Date: Tue, 4 Mar 2014 14:04:11 +0000 Subject: [PATCH 1/3] allow custom sorting of toHierarchy result allow custom sorting of toHierarchy result, using a arbitrary comparator function with uasort. Fixes #41. Possibly not as efficient as a pure SQL solution depending on the complexity of the sort and the number or records but for simple comparison its fairly elegant. example to sort by "name" attribute of node ``` $sorted = Category::all()->toHierarchy(function($a,$b){ return strcmp($a->name, $b->name);}) ``` --- src/Baum/Extensions/Eloquent/Collection.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Baum/Extensions/Eloquent/Collection.php b/src/Baum/Extensions/Eloquent/Collection.php index 6b62cba4..528e20de 100644 --- a/src/Baum/Extensions/Eloquent/Collection.php +++ b/src/Baum/Extensions/Eloquent/Collection.php @@ -5,13 +5,13 @@ class Collection extends BaseCollection { - public function toHierarchy() { + public function toHierarchy($cmp=false) { $tree = $this->items; - return new BaseCollection($this->hierarchical($tree)); + return new BaseCollection($this->hierarchical($tree, $cmp)); } - protected function hierarchical(&$result) { + protected function hierarchical(&$result, $cmp=false) { $new = array(); if ( is_array($result) ) { @@ -19,15 +19,21 @@ protected function hierarchical(&$result) { $new[$sub->getKey()] = $sub; if ( ! $sub->isLeaf() ) - $new[$sub->getKey()]->setRelation('children', new BaseCollection($this->hierarchical($result))); + $new[$sub->getKey()]->setRelation('children', new BaseCollection($this->hierarchical($result,$cmp))); $next_id = key($result); - if ( $next_id && $result[$next_id]->getParentId() != $sub->getParentId() ) + if ( $next_id && $result[$next_id]->getParentId() != $sub->getParentId() ){ + if(is_callable($cmp)){ + uasort($new,$cmp); + } return $new; + } } } - + if(is_callable($cmp)){ + uasort($new,$cmp); + } return $new; } From ef1360cb243272991ffa840e36f6cd91d2b9d985 Mon Sep 17 00:00:00 2001 From: shaddowgh Date: Tue, 4 Mar 2014 14:47:27 +0000 Subject: [PATCH 2/3] prevent uneeded children calls on leafs set children relation to empty array for leaf nodes to prevent them from being re-queried when iterating over tree in template or such. --- src/Baum/Extensions/Eloquent/Collection.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Baum/Extensions/Eloquent/Collection.php b/src/Baum/Extensions/Eloquent/Collection.php index 528e20de..1e9b5ee2 100644 --- a/src/Baum/Extensions/Eloquent/Collection.php +++ b/src/Baum/Extensions/Eloquent/Collection.php @@ -18,9 +18,11 @@ protected function hierarchical(&$result, $cmp=false) { while( list($n, $sub) = each($result) ) { $new[$sub->getKey()] = $sub; - if ( ! $sub->isLeaf() ) + if ( ! $sub->isLeaf() ){ $new[$sub->getKey()]->setRelation('children', new BaseCollection($this->hierarchical($result,$cmp))); - + }else{ + $new[$sub->getKey()]->setRelation('children',array()); + } $next_id = key($result); if ( $next_id && $result[$next_id]->getParentId() != $sub->getParentId() ){ From 60f8181c8eaa607bf4954a4ed73df6f43038eb03 Mon Sep 17 00:00:00 2001 From: shaddowgh Date: Tue, 4 Mar 2014 15:56:03 +0000 Subject: [PATCH 3/3] fix for tests tests expect a collection object as they use its count function so return an empty collection rather than an empty array. --- src/Baum/Extensions/Eloquent/Collection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Baum/Extensions/Eloquent/Collection.php b/src/Baum/Extensions/Eloquent/Collection.php index 1e9b5ee2..142a47b9 100644 --- a/src/Baum/Extensions/Eloquent/Collection.php +++ b/src/Baum/Extensions/Eloquent/Collection.php @@ -21,7 +21,7 @@ protected function hierarchical(&$result, $cmp=false) { if ( ! $sub->isLeaf() ){ $new[$sub->getKey()]->setRelation('children', new BaseCollection($this->hierarchical($result,$cmp))); }else{ - $new[$sub->getKey()]->setRelation('children',array()); + $new[$sub->getKey()]->setRelation('children',new BaseCollection(array())); } $next_id = key($result);