From e02f7facfdf4cc647ee4ca40865794fc32fd1ea9 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Sun, 23 Jun 2013 23:52:32 +0200 Subject: [PATCH] Moved the creation from array and from node outside the item factory They are now handled by loaders --- CHANGELOG.md | 3 + src/Knp/Menu/FactoryInterface.php | 20 ---- src/Knp/Menu/Loader/ArrayLoader.php | 61 ++++++++++ src/Knp/Menu/Loader/LoaderInterface.php | 26 +++++ src/Knp/Menu/Loader/NodeLoader.php | 36 ++++++ src/Knp/Menu/MenuFactory.php | 48 +++++--- .../Knp/Menu/Tests/Loader/ArrayLoaderTest.php | 107 ++++++++++++++++++ tests/Knp/Menu/Tests/MenuFactoryTest.php | 66 ++--------- 8 files changed, 275 insertions(+), 92 deletions(-) create mode 100644 src/Knp/Menu/Loader/ArrayLoader.php create mode 100644 src/Knp/Menu/Loader/LoaderInterface.php create mode 100644 src/Knp/Menu/Loader/NodeLoader.php create mode 100644 tests/Knp/Menu/Tests/Loader/ArrayLoaderTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 24d67739..b006b765 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## 2.0.0 (2013-XX-XX) +* [BC break] Deprecated the methods `createFromArray` and `createFromNode` in the MenuFactory and + removed them from `Knp\Menu\FactoryInterface`. Use `Knp\Menu\Loader\ArrayLoader` and + `Knp\Menu\Loader\NodeLoader` instead. * [BC break] Deprecated the methods `moveToPosition`, `moveToFirstPosition`, `moveToLastPosition`, `moveChildToPosition`, `callRecursively`, `toArray`, `getPathAsString` and `getBreadcrumbsArray` in the MenuItem and removed them from `Knp\Menu\ItemInterface`. Use `Knp\Menu\Util\MenuManipulator` diff --git a/src/Knp/Menu/FactoryInterface.php b/src/Knp/Menu/FactoryInterface.php index 96619424..91debfbb 100644 --- a/src/Knp/Menu/FactoryInterface.php +++ b/src/Knp/Menu/FactoryInterface.php @@ -16,24 +16,4 @@ interface FactoryInterface * @return ItemInterface */ public function createItem($name, array $options = array()); - - /** - * Create a menu item from a NodeInterface - * - * @param NodeInterface $node - * - * @return ItemInterface - */ - public function createFromNode(NodeInterface $node); - - /** - * Creates a new menu item (and tree if $data['children'] is set). - * - * The source is an array of data that should match the output from MenuItem->toArray(). - * - * @param array $data The array of data to use as a source for the menu tree - * - * @return ItemInterface - */ - public function createFromArray(array $data); } diff --git a/src/Knp/Menu/Loader/ArrayLoader.php b/src/Knp/Menu/Loader/ArrayLoader.php new file mode 100644 index 00000000..98c7861f --- /dev/null +++ b/src/Knp/Menu/Loader/ArrayLoader.php @@ -0,0 +1,61 @@ +factory = $factory; + } + + public function load($data) + { + if (!$this->supports($data)) { + throw new \InvalidArgumentException(sprintf('Unsupported data. Expected an array but got ', is_object($data) ? get_class($data) : gettype($data))); + } + + return $this->fromArray($data); + } + + public function supports($data) + { + return is_array($data); + } + + /** + * @param array $data + * @param string|null $name (the name of the item, used only if there is no name in the data themselves) + * + * @return ItemInterface + */ + private function fromArray(array $data, $name = null) + { + $name = isset($data['name']) ? $data['name'] : $name; + + if (isset($data['children'])) { + $children = $data['children']; + unset($data['children']); + } else { + $children = array(); + } + + $item = $this->factory->createItem($name, $data); + + foreach ($children as $name => $child) { + $item->addChild($this->fromArray($child, $name)); + } + + return $item; + } +} diff --git a/src/Knp/Menu/Loader/LoaderInterface.php b/src/Knp/Menu/Loader/LoaderInterface.php new file mode 100644 index 00000000..2536dd8c --- /dev/null +++ b/src/Knp/Menu/Loader/LoaderInterface.php @@ -0,0 +1,26 @@ +factory = $factory; + } + + public function load($data) + { + if (!$data instanceof NodeInterface) { + throw new \InvalidArgumentException(sprintf('Unsupported data. Expected Knp\Menu\NodeInterface but got ', is_object($data) ? get_class($data) : gettype($data))); + } + + $item = $this->factory->createItem($data->getName(), $data->getOptions()); + + foreach ($data->getChildren() as $childNode) { + $item->addChild($this->load($childNode)); + } + + return $item; + } + + public function supports($data) + { + return $data instanceof NodeInterface; + } +} diff --git a/src/Knp/Menu/MenuFactory.php b/src/Knp/Menu/MenuFactory.php index 373d3aa8..b37e337c 100644 --- a/src/Knp/Menu/MenuFactory.php +++ b/src/Knp/Menu/MenuFactory.php @@ -2,6 +2,9 @@ namespace Knp\Menu; +use Knp\Menu\Loader\ArrayLoader; +use Knp\Menu\Loader\NodeLoader; + /** * Factory to create a menu from a tree */ @@ -63,32 +66,41 @@ protected function configureItem(ItemInterface $item, array $options) ; } + /** + * Create a menu item from a NodeInterface + * + * @deprecated Use \Knp\Menu\Loader\NodeLoader + * + * @param NodeInterface $node + * + * @return ItemInterface + */ public function createFromNode(NodeInterface $node) { - $item = $this->createItem($node->getName(), $node->getOptions()); + trigger_error(__METHOD__ . ' is deprecated. Use Knp\Menu\Loader\NodeLoader instead', E_USER_DEPRECATED); - foreach ($node->getChildren() as $childNode) { - $item->addChild($this->createFromNode($childNode)); - } + $loader = new NodeLoader($this); - return $item; + return $loader->load($node); } - public function createFromArray(array $data, $name = null) + /** + * Creates a new menu item (and tree if $data['children'] is set). + * + * The source is an array of data that should match the output from MenuManipulator->toArray(). + * + * @deprecated Use \Knp\Menu\Loader\ArrayLoader + * + * @param array $data The array of data to use as a source for the menu tree + * + * @return ItemInterface + */ + public function createFromArray(array $data) { - $name = isset($data['name']) ? $data['name'] : $name; - if (isset($data['children'])) { - $children = $data['children']; - unset($data['children']); - } else { - $children = array(); - } + trigger_error(__METHOD__ . ' is deprecated. Use Knp\Menu\Loader\ArrayLoader instead', E_USER_DEPRECATED); - $item = $this->createItem($name, $data); - foreach ($children as $name => $child) { - $item->addChild($this->createFromArray($child, $name)); - } + $loader = new ArrayLoader($this); - return $item; + return $loader->load($data); } } diff --git a/tests/Knp/Menu/Tests/Loader/ArrayLoaderTest.php b/tests/Knp/Menu/Tests/Loader/ArrayLoaderTest.php new file mode 100644 index 00000000..fcd4f761 --- /dev/null +++ b/tests/Knp/Menu/Tests/Loader/ArrayLoaderTest.php @@ -0,0 +1,107 @@ + 'joe', + 'uri' => '/foobar', + 'display' => false, + ); + + $loader = new ArrayLoader(new MenuFactory()); + $item = $loader->load($array); + + $this->assertEquals('joe', $item->getName()); + $this->assertEquals('/foobar', $item->getUri()); + $this->assertFalse($item->isDisplayed()); + $this->assertEmpty($item->getAttributes()); + $this->assertEmpty($item->getChildren()); + } + + public function testLoadWithChildren() + { + $array = array( + 'name' => 'joe', + 'children' => array( + 'jack' => array( + 'name' => 'jack', + 'label' => 'Jack', + ), + array( + 'name' => 'john' + ) + ), + ); + + $loader = new ArrayLoader(new MenuFactory()); + $item = $loader->load($array); + + $this->assertEquals('joe', $item->getName()); + $this->assertEmpty($item->getAttributes()); + $this->assertCount(2, $item); + $this->assertTrue(isset($item['john'])); + } + + public function testLoadWithChildrenOmittingName() + { + $array = array( + 'name' => 'joe', + 'children' => array( + 'jack' => array( + 'label' => 'Jack', + ), + 'john' => array( + 'label' => 'John' + ) + ), + ); + + $loader = new ArrayLoader(new MenuFactory()); + $item = $loader->load($array); + + $this->assertEquals('joe', $item->getName()); + $this->assertEmpty($item->getAttributes()); + $this->assertCount(2, $item); + $this->assertTrue(isset($item['john'])); + $this->assertTrue(isset($item['jack'])); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testLoadInvalidData() + { + $loader = new ArrayLoader(new MenuFactory()); + + $loader->load(new \stdClass()); + } + + /** + * @dataProvider provideSupportingData + */ + public function testSupports($data, $expected) + { + $loader = new ArrayLoader(new MenuFactory()); + + $this->assertSame($expected, $loader->supports($data)); + } + + public function provideSupportingData() + { + return array( + array(array(), true), + array(null, false), + array('foobar', false), + array(new \stdClass(), false), + array(53, false), + array(true, false), + ); + } +} diff --git a/tests/Knp/Menu/Tests/MenuFactoryTest.php b/tests/Knp/Menu/Tests/MenuFactoryTest.php index 7c96381f..6fd4be74 100644 --- a/tests/Knp/Menu/Tests/MenuFactoryTest.php +++ b/tests/Knp/Menu/Tests/MenuFactoryTest.php @@ -6,63 +6,21 @@ class MenuFactoryTest extends \PHPUnit_Framework_TestCase { - public function testFromArrayWithoutChildren() + public function testCreateItem() { $factory = new MenuFactory(); - $array = array( - 'name' => 'joe', - 'uri' => '/foobar', - 'display' => false, - ); - $item = $factory->createFromArray($array); - $this->assertEquals('joe', $item->getName()); - $this->assertEquals('/foobar', $item->getUri()); - $this->assertFalse($item->isDisplayed()); - $this->assertEmpty($item->getAttributes()); - $this->assertEmpty($item->getChildren()); - } - public function testFromArrayWithChildren() - { - $factory = new MenuFactory(); - $array = array( - 'name' => 'joe', - 'children' => array( - 'jack' => array( - 'name' => 'jack', - 'label' => 'Jack', - ), - array( - 'name' => 'john' - ) - ), - ); - $item = $factory->createFromArray($array); - $this->assertEquals('joe', $item->getName()); - $this->assertEmpty($item->getAttributes()); - $this->assertCount(2, $item); - $this->assertTrue(isset($item['john'])); - } + $item = $factory->createItem('test', array( + 'uri' => 'http://example.com', + 'linkAttributes' => array('class' => 'foo'), + 'display' => false, + 'displayChildren' => false, + )); - public function testFromArrayWithChildrenOmittingName() - { - $factory = new MenuFactory(); - $array = array( - 'name' => 'joe', - 'children' => array( - 'jack' => array( - 'label' => 'Jack', - ), - 'john' => array( - 'label' => 'John' - ) - ), - ); - $item = $factory->createFromArray($array); - $this->assertEquals('joe', $item->getName()); - $this->assertEmpty($item->getAttributes()); - $this->assertCount(2, $item); - $this->assertTrue(isset($item['john'])); - $this->assertTrue(isset($item['jack'])); + $this->assertInstanceOf('Knp\Menu\ItemInterface', $item); + $this->assertEquals('test', $item->getName()); + $this->assertFalse($item->isDisplayed()); + $this->assertFalse($item->getDisplayChildren()); + $this->assertEquals('foo', $item->getLinkAttribute('class')); } }