mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-28 02:23:51 +00:00
integration of knp menu bundle
This commit is contained in:
38
Routing/LocalMenuBuilderInterface.php
Normal file
38
Routing/LocalMenuBuilderInterface.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2018 Champs Libres Cooperative <info@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Chill\MainBundle\Routing;
|
||||
|
||||
use Knp\Menu\MenuItem;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
interface LocalMenuBuilderInterface
|
||||
{
|
||||
/**
|
||||
* return an array of menu ids
|
||||
*
|
||||
* @internal this method is static to 1. keep all config in the class,
|
||||
* instead of tags arguments; 2. avoid a "supports" method, which could lead
|
||||
* to parsing all instances to get only one or two working instance.
|
||||
*/
|
||||
public static function getMenuIds(): array;
|
||||
|
||||
public function buildMenu($menuId, MenuItem $menu, array $parameters);
|
||||
}
|
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -64,7 +64,10 @@ class MenuTwig extends \Twig_Extension implements ContainerAwareInterface
|
||||
public function getFunctions()
|
||||
{
|
||||
return [new \Twig_SimpleFunction('chill_menu',
|
||||
array($this, 'chillMenu'), array('is_safe' => array('html')))
|
||||
array($this, 'chillMenu'), array(
|
||||
'is_safe' => array('html'),
|
||||
'needs_environment' => true
|
||||
))
|
||||
];
|
||||
}
|
||||
|
||||
@@ -81,17 +84,22 @@ class MenuTwig extends \Twig_Extension implements ContainerAwareInterface
|
||||
* @param string $menuId
|
||||
* @param mixed[] $params
|
||||
*/
|
||||
public function chillMenu($menuId, array $params = array())
|
||||
public function chillMenu(\Twig_Environment $env, $menuId, array $params = array())
|
||||
{
|
||||
$resolvedParams = array_merge($this->defaultParams, $params);
|
||||
|
||||
$layout = $resolvedParams['layout'];
|
||||
unset($resolvedParams['layout']);
|
||||
|
||||
$resolvedParams['routes'] = $this->menuComposer->getRoutesFor($menuId);
|
||||
if ($this->menuComposer->hasLocalMenuBuilder($menuId) === false) {
|
||||
$resolvedParams['routes'] = $this->menuComposer->getRoutesFor($menuId, $resolvedParams);
|
||||
|
||||
return $this->container->get('templating')
|
||||
->render($layout, $resolvedParams);
|
||||
return $env->render($layout, $resolvedParams);
|
||||
} else {
|
||||
$resolvedParams['menus'] = $this->menuComposer->getMenuFor($menuId, $resolvedParams);
|
||||
|
||||
return $env->render($layout, $resolvedParams);
|
||||
}
|
||||
}
|
||||
|
||||
public function getName()
|
||||
|
Reference in New Issue
Block a user