Skip to content

Commit

Permalink
Added Collection::listNested()
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Apr 6, 2014
1 parent b8e780a commit b4df00f
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/Collection/CollectionTrait.php
Expand Up @@ -21,8 +21,10 @@
use Cake\Collection\Iterator\FilterIterator;
use Cake\Collection\Iterator\InsertIterator;
use Cake\Collection\Iterator\MapReduce;
use Cake\Collection\Iterator\NestIterator;
use Cake\Collection\Iterator\ReplaceIterator;
use Cake\Collection\Iterator\SortIterator;
use Cake\Collection\Iterator\TreeIterator;
use LimitIterator;

/**
Expand Down Expand Up @@ -857,4 +859,16 @@ public function compile($preserveKeys = true) {
return new Collection($this->toArray($preserveKeys));
}

/**
*
*
* @return void
*/
public function listNested($nestingKey = 'children') {
return new TreeIterator(
new NestIterator($this, $nestingKey),
TreeIterator::SELF_FIRST
);
}

}
48 changes: 48 additions & 0 deletions src/Collection/Iterator/NestIterator.php
@@ -0,0 +1,48 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\Collection\Iterator;

use Cake\Collection\Collection;
use RecursiveIterator;

class NestIterator extends Collection implements RecursiveIterator{

protected $_nestKey;

public function __construct($items, $nestKey) {
parent::__construct($items);
$this->_nestKey = $nestKey;
}

public function getChildren() {
$property = $this->_propertyExtractor($this->_nestKey);
return new self($property($this->current()), $this->_nestKey);
}

public function hasChildren () {
$property = $this->_propertyExtractor($this->_nestKey);
$children = $property($this->current());

if (is_array($children)) {
return !empty($children);
}

if ($children instanceof \Traversable) {
return true;
}

return false;
}
}
24 changes: 24 additions & 0 deletions src/Collection/Iterator/TreeIterator.php
@@ -0,0 +1,24 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\Collection\Iterator;

use Cake\Collection\CollectionTrait;
use RecursiveIteratorIterator;

class TreeIterator extends RecursiveIteratorIterator {

use CollectionTrait;

}
39 changes: 39 additions & 0 deletions tests/TestCase/Collection/CollectionTest.php
Expand Up @@ -872,4 +872,43 @@ public function testInsert() {
);
}

/**
* Tests the listNested method with the default 'children' nesting key
*
* @return void
*/
public function testListNested() {
$items = [
['id' => 1, 'parent_id' => null],
['id' => 2, 'parent_id' => 1],
['id' => 3, 'parent_id' => 2],
['id' => 4, 'parent_id' => 2],
['id' => 5, 'parent_id' => 3],
['id' => 6, 'parent_id' => null],
['id' => 7, 'parent_id' => 3],
['id' => 8, 'parent_id' => 4],
['id' => 9, 'parent_id' => 6],
['id' => 10, 'parent_id' => 6]
];
$collection = (new Collection($items))->nest('id', 'parent_id')->listNested();
$this->assertEquals(
[1, 2, 3, 5, 7, 4, 8, 6, 9, 10],
$collection->extract('id')->toArray(false)
);
}

/**
* Tests using listNested with a different nesting key
*
* @return void
*/
public function testListNestedCustomKey() {
$items = [
['id' => 1, 'stuff' => [['id' => 2, 'stuff' => [['id' => 3]]]]],
['id' => 4, 'stuff' => [['id' => 5]]]
];
$collection = (new Collection($items))->listNested('stuff');
$this->assertEquals(range(1, 5), $collection->extract('id')->toArray(false));
}

}

0 comments on commit b4df00f

Please sign in to comment.