Skip to content
This repository was archived by the owner on Sep 16, 2021. It is now read-only.

Commit 247928e

Browse files
committed
cleanup the menu creation event and improve doc
1 parent fde5bfd commit 247928e

File tree

9 files changed

+171
-61
lines changed

9 files changed

+171
-61
lines changed

CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
Changelog
22
=========
33

4+
* **2014-04-04**: The menu factory now raises an event when a menu item is
5+
built from a menu node. The event can be used to change the behaviour or
6+
skip building the menu item altogether.
7+
48
* **2014-03-24**: setParent() and getParent() are now deprecated.
59
Use setParentDocument() and getParentDocument() instead.
610
Moreover, you should now enable the ChildExtension from the CoreBundle.
@@ -16,8 +20,8 @@ Changelog
1620
$ php app/console doctrine:phpcr:nodes:update \
1721
--query="SELECT * FROM [nt:base] WHERE [phpcr:class] = 'Symfony\\Cmf\\Bundle\\MenuBundle\\Doctrine\\Phpcr\\Menu' OR [phpcr:class] = 'Symfony\\Cmf\\Bundle\\MenuBundle\\Doctrine\\Phpcr\\MenuNode'" \
1822
--apply-closure="$node->addMixin('mix:referenceable');"
19-
20-
* **2013-11-25**: [PublishWorkflow] added a `MenuContentVoter`, this voter
23+
24+
* **2013-11-25**: [PublishWorkflow] added a `MenuContentVoter`, this voter
2125
decides that a menu node is not published if the content it is pointing to is
2226
not published.
2327

ContentAwareFactory.php

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
use Psr\Log\LoggerInterface;
2020

21+
use Symfony\Cmf\Bundle\MenuBundle\Event\Events;
22+
use Symfony\Cmf\Bundle\MenuBundle\Model\Menu;
2123
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
2224
use Symfony\Component\Routing\Exception\RouteNotFoundException;
2325

@@ -68,23 +70,24 @@ class ContentAwareFactory extends RouterAwareFactory
6870
private $allowEmptyItems;
6971

7072
/**
71-
* @param UrlGeneratorInterface $generator for the parent class
72-
* @param UrlGeneratorInterface $contentRouter to generate routes when
73+
* @param UrlGeneratorInterface $generator for the parent class
74+
* @param UrlGeneratorInterface $contentRouter to generate routes when
7375
* content is set
74-
* @param LoggerInterface $logger
76+
* @param EventDispatcherInterface $dispatcher to dispatch the CREATE_ITEM_FROM_NODE event.
77+
* @param LoggerInterface $logger
7578
*/
7679
public function __construct(
7780
UrlGeneratorInterface $generator,
7881
UrlGeneratorInterface $contentRouter,
79-
LoggerInterface $logger,
80-
EventDispatcherInterface $dispatcher
82+
EventDispatcherInterface $dispatcher,
83+
LoggerInterface $logger
8184
)
8285
{
8386
parent::__construct($generator);
8487
$this->contentRouter = $contentRouter;
85-
$this->logger = $logger;
8688
$this->linkTypes = array('route', 'uri', 'content');
8789
$this->dispatcher = $dispatcher;
90+
$this->logger = $logger;
8891
}
8992

9093
/**
@@ -144,9 +147,14 @@ private function getVoters()
144147
public function createFromNode(NodeInterface $node)
145148
{
146149
$event = new CreateMenuItemFromNodeEvent($node, $this);
147-
$this->dispatcher->dispatch('cmf_menu.create_menu_item_from_node', $event);
150+
$this->dispatcher->dispatch(Events::CREATE_ITEM_FROM_NODE, $event);
151+
152+
if ($event->isSkipNode()) {
153+
if ($node instanceof Menu) {
154+
// create an empty menu root to avoid the knp menu from failing.
155+
return $this->createItem('');
156+
}
148157

149-
if ($event->getSkipNode()) {
150158
return null;
151159
}
152160

@@ -156,23 +164,24 @@ public function createFromNode(NodeInterface $node)
156164
return null;
157165
}
158166

159-
if ($event->getSkipChildren()) {
167+
if ($event->isSkipChildren()) {
160168
return $item;
161169
}
162170

163-
return $this->addChildrenFromNode($node, $item);
171+
return $this->addChildrenFromNode($node->getChildren(), $item);
164172
}
165173

166174
/**
167-
* Add children to a menu item from a node
175+
* Create menu items from a list of menu nodes and add them to $item.
176+
*
177+
* @param NodeInterface[] $node The menu nodes to create.
178+
* @param ItemInterface $item The menu item to add the children to.
168179
*
169-
* @param NodeInterface $node
170-
* @param ItemInterface $item
171180
* @return ItemInterface
172181
*/
173-
public function addChildrenFromNode(NodeInterface $node, ItemInterface $item)
182+
public function addChildrenFromNode($nodes, ItemInterface $item)
174183
{
175-
foreach ($node->getChildren() as $childNode) {
184+
foreach ($nodes as $childNode) {
176185
if ($childNode instanceof NodeInterface) {
177186
$child = $this->createFromNode($childNode);
178187
if (!empty($child)) {

Event/CreateMenuItemFromNodeEvent.php

Lines changed: 93 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,52 +3,65 @@
33
/*
44
* This file is part of the Symfony CMF package.
55
*
6-
* (c) 2011-2013 Symfony CMF
6+
* (c) 2011-2014 Symfony CMF
77
*
88
* For the full copyright and license information, please view the LICENSE
99
* file that was distributed with this source code.
1010
*/
1111

1212
namespace Symfony\Cmf\Bundle\MenuBundle\Event;
1313

14-
use Knp\Menu\MenuItem;
14+
use Knp\Menu\ItemInterface;
1515
use Knp\Menu\NodeInterface;
1616

1717
use Symfony\Component\EventDispatcher\Event;
1818

1919
use Symfony\Cmf\Bundle\MenuBundle\ContentAwareFactory;
2020

21+
/**
22+
* This event is raised when a menu node is to be transformed into a menu item.
23+
*
24+
* The event allows to control whether the menu node should be handled or to
25+
* completely replace the default behaviour of converting a menu node to a menu
26+
* item.
27+
*
28+
* @author Ben Glassman <[email protected]>
29+
*/
2130
class CreateMenuItemFromNodeEvent extends Event
2231
{
2332
/**
2433
* @var NodeInterface
2534
*/
26-
protected $node;
35+
private $node;
2736

2837
/**
29-
* @var ContentAwareFactory
38+
* @var ItemInterface
3039
*/
31-
protected $factory;
40+
private $item;
3241

3342
/**
34-
* @var MenuItem
43+
* @var ContentAwareFactory
3544
*/
36-
protected $item;
45+
private $factory;
3746

3847
/**
3948
* Whether or not to skip processing of this node
40-
*
49+
*
4150
* @var boolean
4251
*/
43-
protected $skipNode = false;
52+
private $skipNode = false;
4453

4554
/**
4655
* Whether or not to skip processing of child nodes
47-
*
56+
*
4857
* @var boolean
4958
*/
50-
protected $skipChildren = false;
59+
private $skipChildren = false;
5160

61+
/**
62+
* @param NodeInterface $node
63+
* @param ContentAwareFactory $factory
64+
*/
5265
public function __construct(
5366
NodeInterface $node,
5467
ContentAwareFactory $factory
@@ -57,44 +70,100 @@ public function __construct(
5770
$this->factory = $factory;
5871
}
5972

60-
public function getItem()
61-
{
62-
return $this->item;
63-
}
64-
65-
public function setItem(MenuItem $item = null)
73+
/**
74+
* Get the menu node that is about to be built.
75+
*
76+
* @return NodeInterface
77+
*/
78+
public function getNode()
6679
{
67-
$this->item = $item;
80+
return $this->node;
6881
}
6982

70-
public function getFactory()
83+
/**
84+
* Get the menu item attached to this event.
85+
*
86+
* If this is non-null, it will be used instead of automatically converting
87+
* the NodeInterface into a MenuItem.
88+
*
89+
* @return ItemInterface
90+
*/
91+
public function getItem()
7192
{
72-
return $this->factory;
93+
return $this->item;
7394
}
7495

75-
public function getNode()
96+
/**
97+
* Set the menu item that represents the menu node of this event.
98+
*
99+
* Unless you set the skip children option, the children from the menu node
100+
* will still be built and added after eventual children this menu item
101+
* has.
102+
*
103+
* @param ItemInterface $item Menu item to use.
104+
*/
105+
public function setItem(ItemInterface $item = null)
76106
{
77-
return $this->node;
107+
$this->item = $item;
78108
}
79109

110+
/**
111+
* Set whether the node associated with this event is to be skipped
112+
* entirely. This has precedence over an eventual menu item attached to the
113+
* event.
114+
*
115+
* This automatically skips the whole subtree, as the children have no
116+
* place where they could be attached to.
117+
*
118+
* @param bool $skipNode
119+
*/
80120
public function setSkipNode($skipNode)
81121
{
82122
$this->skipNode = (bool) $skipNode;
83123
}
84124

85-
public function getSkipNode()
125+
/**
126+
* @return bool Whether the node associated to this event is to be skipped.
127+
*/
128+
public function isSkipNode()
86129
{
87130
return $this->skipNode;
88131
}
89132

133+
/**
134+
* Set whether the children of the *node* associated with this event should
135+
* be ignored.
136+
*
137+
* Use this for example when your event handler implements its own logic to
138+
* build children items for the node associated with this event.
139+
*
140+
* If this event has a menu *item*, those children won't be skipped.
141+
*
142+
* @param bool $skipChildren
143+
*/
90144
public function setSkipChildren($skipChildren)
91145
{
92146
$this->skipChildren = (bool) $skipChildren;
93147
}
94148

95-
public function getSkipChildren()
149+
/**
150+
* @return bool Whether the children of the node associated to this event
151+
* should be handled or ignored.
152+
*/
153+
public function isSkipChildren()
96154
{
97155
return $this->skipChildren;
98156
}
99157

158+
/**
159+
* Get the menu factory that raised this event.
160+
*
161+
* You can use the factory to build a custom menu item.
162+
*
163+
* @return ContentAwareFactory
164+
*/
165+
public function getFactory()
166+
{
167+
return $this->factory;
168+
}
100169
}

Event/Events.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony CMF package.
5+
*
6+
* (c) 2011-2014 Symfony CMF
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Cmf\Bundle\MenuBundle\Event;
13+
14+
final class Events
15+
{
16+
/**
17+
* Fired when a menu item is to be created from a node in ContentAwareFactory
18+
*
19+
* The event object is a CreateMenuItemFromNodeEvent.
20+
*/
21+
const CREATE_ITEM_FROM_NODE = 'cmf_menu.create_menu_item_from_node';
22+
}

Provider/PhpcrMenuProvider.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
1312
namespace Symfony\Cmf\Bundle\MenuBundle\Provider;
1413

1514
use Doctrine\Common\Persistence\ManagerRegistry;

0 commit comments

Comments
 (0)