integration of knp menu bundle

This commit is contained in:
2018-04-30 17:42:24 +02:00
parent 5c045abda4
commit 395787f1bb
10 changed files with 204 additions and 46 deletions

View File

@@ -3,8 +3,9 @@
namespace Chill\MainBundle\Routing;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Routing\RouterInterface;
use Knp\Menu\FactoryInterface;
/**
* This class permit to build menu from the routing information
@@ -14,27 +15,34 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*
* @author julien
*/
class MenuComposer implements ContainerAwareInterface
class MenuComposer
{
/**
*
* @var ContainerInterface
* @var RouterInterface
*/
private $container;
private $router;
/**
*
* @internal using the service router in container cause circular references
* @param ContainerInterface $container
*
* @var FactoryInterface
*/
public function setContainer(ContainerInterface $container = null)
{
if (NULL === $container) {
throw new \LogicException('container should not be null');
}
//see remark in MenuComposer::setRouteCollection
$this->container = $container;
private $menuFactory;
/**
*
* @var
*/
private $localMenuBuilders = [];
function __construct(
RouterInterface $router,
FactoryInterface $menuFactory
) {
$this->router = $router;
$this->menuFactory = $menuFactory;
}
/**
@@ -61,7 +69,7 @@ class MenuComposer implements ContainerAwareInterface
public function getRoutesFor($menuId, array $parameters = array())
{
$routes = array();
$routeCollection = $this->container->get('router')->getRouteCollection();
$routeCollection = $this->router->getRouteCollection();
foreach ($routeCollection->all() as $routeKey => $route) {
if ($route->hasOption('menus')) {
@@ -83,6 +91,35 @@ class MenuComposer implements ContainerAwareInterface
return $routes;
}
public function getMenuFor($menuId, array $parameters = array())
{
$routes = $this->getRoutesFor($menuId, $parameters);
$menu = $this->menuFactory->createItem($menuId);
// build menu from routes
foreach ($routes as $order => $route) {
$menu->addChild($route['label'], [
'route' => $route['key'],
'routeParameters' => $parameters,
'order' => $order
])
->setExtras([
'icon' => $route['icon'],
'order' => $order
])
;
}
if ($this->hasLocalMenuBuilder($menuId)) {
foreach ($this->localMenuBuilders[$menuId] as $builder) {
/* @var $builder LocalMenuBuilderInterface */
$builder->buildMenu($menuId, $menu, $parameters);
}
}
return $menu;
}
/**
* recursive function to resolve the order of a array of routes.
* If the order chosen in routing.yml is already in used, find the
@@ -99,5 +136,25 @@ class MenuComposer implements ContainerAwareInterface
return $order;
}
}
public function addLocalMenuBuilder(LocalMenuBuilderInterface $menuBuilder, $menuId)
{
$this->localMenuBuilders[$menuId][] = $menuBuilder;
}
/**
* Return true if the menu has at least one builder.
*
* This function is a helper to determine if the method `getMenuFor`
* should be used, or `getRouteFor`. The method `getMenuFor` should be used
* if the result is true (it **does** exists at least one menu builder.
*
* @param string $menuId
* @return bool
*/
public function hasLocalMenuBuilder($menuId): bool
{
return \array_key_exists($menuId, $this->localMenuBuilders);
}
}