diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f030563..7d301e6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## 1.1.0 (2012-XX-XX) +* Added a filter iterator keeping only current items +* Made the iterator recursive for the item * Fixed building an array of breadcrumbs when a label has only digits * Added a way to mark a label as safe * Refactored the ListRenderer to be consistent with the TwigRenderer and provide the same extension points diff --git a/src/Knp/Menu/Iterator/CurrentItemFilterIterator.php b/src/Knp/Menu/Iterator/CurrentItemFilterIterator.php new file mode 100644 index 00000000..1d07feb5 --- /dev/null +++ b/src/Knp/Menu/Iterator/CurrentItemFilterIterator.php @@ -0,0 +1,14 @@ +current()->isCurrent(); + } +} diff --git a/src/Knp/Menu/Iterator/ItemIterator.php b/src/Knp/Menu/Iterator/ItemIterator.php new file mode 100644 index 00000000..3d0c04e0 --- /dev/null +++ b/src/Knp/Menu/Iterator/ItemIterator.php @@ -0,0 +1,21 @@ +current(); + + return $current->getIterator() instanceof \RecursiveIterator && 0 < count($current); + } + + public function getChildren() + { + return $this->current()->getIterator(); + } +} diff --git a/src/Knp/Menu/MenuItem.php b/src/Knp/Menu/MenuItem.php index 96020a4f..02f9747f 100644 --- a/src/Knp/Menu/MenuItem.php +++ b/src/Knp/Menu/MenuItem.php @@ -2,6 +2,7 @@ namespace Knp\Menu; +use Knp\Menu\Iterator\ItemIterator; use Knp\Menu\Renderer\RendererInterface; use Knp\Menu\Renderer\ListRenderer; @@ -1116,7 +1117,7 @@ public function count() */ public function getIterator() { - return new \ArrayIterator($this->children); + return new ItemIterator($this->children); } /** diff --git a/tests/Knp/Menu/Tests/Iterator/IteratorTest.php b/tests/Knp/Menu/Tests/Iterator/IteratorTest.php new file mode 100644 index 00000000..52918d39 --- /dev/null +++ b/tests/Knp/Menu/Tests/Iterator/IteratorTest.php @@ -0,0 +1,66 @@ +pt1 as $key => $value) { + $count++; + $this->assertEquals('Child '.$count, $key); + $this->assertEquals('Child '.$count, $value->getLabel()); + } + } + + public function testRecursiveIterator() + { + // Adding an item which does not provide a RecursiveIterator to be sure it works properly. + $child = $this->getMock('Knp\Menu\ItemInterface'); + $child->expects($this->any()) + ->method('getName') + ->will($this->returnValue('Foo')); + $child->expects($this->any()) + ->method('getIterator') + ->will($this->returnValue(new \EmptyIterator())); + $this->menu->addChild($child); + + $names = array(); + foreach (new \RecursiveIteratorIterator($this->menu, \RecursiveIteratorIterator::SELF_FIRST) as $value) { + $names[] = $value->getName(); + } + + $this->assertEquals(array('Parent 1', 'Child 1', 'Child 2', 'Child 3', 'Parent 2', 'Child 4', 'Grandchild 1', 'Foo'), $names); + } + + public function testRecursiveIteratorLeavesOnly() + { + $names = array(); + foreach (new \RecursiveIteratorIterator($this->menu, \RecursiveIteratorIterator::LEAVES_ONLY) as $value) { + $names[] = $value->getName(); + } + + $this->assertEquals(array('Child 1', 'Child 2', 'Child 3', 'Grandchild 1'), $names); + } + + public function testFilterIterator() + { + $this->pt1->setCurrent(true); + $this->ch2->setCurrent(true); + $this->gc1->setCurrent(true); + + $names = array(); + $iterator = new CurrentItemFilterIterator( + new \RecursiveIteratorIterator($this->menu, \RecursiveIteratorIterator::SELF_FIRST) + ); + foreach ($iterator as $value) { + $names[] = $value->getName(); + } + + $this->assertEquals(array('Parent 1', 'Child 2', 'Grandchild 1'), $names); + } +} diff --git a/tests/Knp/Menu/Tests/MenuItemTreeTest.php b/tests/Knp/Menu/Tests/MenuItemTreeTest.php index 47e1490e..01accca2 100644 --- a/tests/Knp/Menu/Tests/MenuItemTreeTest.php +++ b/tests/Knp/Menu/Tests/MenuItemTreeTest.php @@ -2,82 +2,14 @@ namespace Knp\Menu\Tests; +use Knp\Menu\Iterator\CurrentItemFilterIterator; use Knp\Menu\MenuItem; use Knp\Menu\MenuFactory; class TestMenuItem extends MenuItem {} -class MenuItemTreeTest extends \PHPUnit_Framework_TestCase +class MenuItemTreeTest extends TestCase { - /** - * @var \Knp\Menu\MenuItem - */ - private $menu; - - /** - * @var \Knp\Menu\MenuItem - */ - private $pt1; - - /** - * @var \Knp\Menu\MenuItem - */ - private $ch1; - - /** - * @var \Knp\Menu\MenuItem - */ - private $ch2; - - /** - * @var \Knp\Menu\MenuItem - */ - private $ch3; - - /** - * @var \Knp\Menu\MenuItem - */ - private $pt2; - - /** - * @var \Knp\Menu\MenuItem - */ - private $ch4; - - /** - * @var \Knp\Menu\MenuItem - */ - private $gc1; - - public function setUp() - { - $factory = new MenuFactory(); - $this->menu = $factory->createItem('Root li', array('attributes' => array('class' => 'root'))); - $this->pt1 = $this->menu->addChild('Parent 1'); - $this->ch1 = $this->pt1->addChild('Child 1'); - $this->ch2 = $this->pt1->addChild('Child 2'); - - // add the 3rd child via addChild with an object - $this->ch3 = new MenuItem('Child 3', $factory); - $this->pt1->addChild($this->ch3); - - $this->pt2 = $this->menu->addChild('Parent 2'); - $this->ch4 = $this->pt2->addChild('Child 4'); - $this->gc1 = $this->ch4->addChild('Grandchild 1'); - } - - public function tearDown() - { - $this->menu = null; - $this->pt1 = null; - $this->ch1 = null; - $this->ch2 = null; - $this->ch3 = null; - $this->pt2 = null; - $this->ch4 = null; - $this->gc1 = null; - } - public function testSampleTreeIntegrity() { $this->assertCount(2, $this->menu); @@ -210,16 +142,6 @@ public function testCountable() $this->assertCount(2, $this->menu); } - public function testIterator() - { - $count = 0; - foreach ($this->pt1 as $key => $value) { - $count++; - $this->assertEquals('Child '.$count, $key); - $this->assertEquals('Child '.$count, $value->getLabel()); - } - } - public function testGetChildren() { $children = $this->ch4->getChildren(); @@ -453,17 +375,4 @@ protected function addChildWithExternalUrl() { $this->menu->addChild('child', array('uri' => 'http://www.symfony-reloaded.org')); } - - // prints a visual representation of our basic testing tree - protected function printTestTree() - { - print(' Menu Structure '."\n"); - print(' rt '."\n"); - print(' / \ '."\n"); - print(' pt1 pt2 '."\n"); - print(' / | \ | '."\n"); - print(' ch1 ch2 ch3 ch4 '."\n"); - print(' | '."\n"); - print(' gc1 '."\n"); - } } diff --git a/tests/Knp/Menu/Tests/TestCase.php b/tests/Knp/Menu/Tests/TestCase.php new file mode 100644 index 00000000..bea9f8a0 --- /dev/null +++ b/tests/Knp/Menu/Tests/TestCase.php @@ -0,0 +1,92 @@ +menu = $factory->createItem('Root li', array('attributes' => array('class' => 'root'))); + $this->pt1 = $this->menu->addChild('Parent 1'); + $this->ch1 = $this->pt1->addChild('Child 1'); + $this->ch2 = $this->pt1->addChild('Child 2'); + + // add the 3rd child via addChild with an object + $this->ch3 = new MenuItem('Child 3', $factory); + $this->pt1->addChild($this->ch3); + + $this->pt2 = $this->menu->addChild('Parent 2'); + $this->ch4 = $this->pt2->addChild('Child 4'); + $this->gc1 = $this->ch4->addChild('Grandchild 1'); + } + + protected function tearDown() + { + $this->menu = null; + $this->pt1 = null; + $this->ch1 = null; + $this->ch2 = null; + $this->ch3 = null; + $this->pt2 = null; + $this->ch4 = null; + $this->gc1 = null; + } + + // prints a visual representation of our basic testing tree + protected function printTestTree() + { + print(' Menu Structure '."\n"); + print(' rt '."\n"); + print(' / \ '."\n"); + print(' pt1 pt2 '."\n"); + print(' / | \ | '."\n"); + print(' ch1 ch2 ch3 ch4 '."\n"); + print(' | '."\n"); + print(' gc1 '."\n"); + } +}