Skip to content

Commit

Permalink
Moved the creation from array and from node outside the item factory
Browse files Browse the repository at this point in the history
They are now handled by loaders
  • Loading branch information
stof committed Jun 23, 2013
1 parent f1363cc commit e02f7fa
Show file tree
Hide file tree
Showing 8 changed files with 275 additions and 92 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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`
Expand Down
20 changes: 0 additions & 20 deletions src/Knp/Menu/FactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
61 changes: 61 additions & 0 deletions src/Knp/Menu/Loader/ArrayLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace Knp\Menu\Loader;

use Knp\Menu\FactoryInterface;
use Knp\Menu\ItemInterface;

/**
* Loader importing a menu tree from an array.
*
* The array should match the output of MenuManipulator::toArray
*/
class ArrayLoader implements LoaderInterface
{
private $factory;

public function __construct(FactoryInterface $factory)
{
$this->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;
}
}
26 changes: 26 additions & 0 deletions src/Knp/Menu/Loader/LoaderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Knp\Menu\Loader;

use Knp\Menu\ItemInterface;

interface LoaderInterface
{
/**
* Loads the data into a menu item
*
* @param mixed $data
*
* @return ItemInterface
*/
public function load($data);

/**
* Checks whether the loader can load these data
*
* @param mixed $data
*
* @return boolean
*/
public function supports($data);
}
36 changes: 36 additions & 0 deletions src/Knp/Menu/Loader/NodeLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Knp\Menu\Loader;

use Knp\Menu\FactoryInterface;
use Knp\Menu\NodeInterface;

class NodeLoader implements LoaderInterface
{
private $factory;

public function __construct(FactoryInterface $factory)
{
$this->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;
}
}
48 changes: 30 additions & 18 deletions src/Knp/Menu/MenuFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);
}
}
107 changes: 107 additions & 0 deletions tests/Knp/Menu/Tests/Loader/ArrayLoaderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

namespace Knp\Menu\Tests\Loader;

use Knp\Menu\Loader\ArrayLoader;
use Knp\Menu\MenuFactory;

class ArrayLoaderTest extends \PHPUnit_Framework_TestCase
{
public function testLoadWithoutChildren()
{
$array = array(
'name' => '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),
);
}
}
Loading

0 comments on commit e02f7fa

Please sign in to comment.