2017-10-17 3 views
1

Je dynamique je travaille avec symfony 3.3 et 2.2 knpMenu j'enregistrer un constructeur de menu comme un serviceknpMenu ne peut pas ajouter route

lilworks_store.menu_builder: 
    class: LilWorks\StoreBundle\Menu\MenuBuilder 
    arguments: ["@knp_menu.factory","@request_stack"] 
    tags: 
     - { name: knp_menu.menu_builder, method: createMainMenu, alias: main } # The alias is what is used to retrieve the menu 

je peux rendre un menu simple sans aucun problème. Mais lorsque je tente de la route avec des paramètres avait j'ai une erreur

Une exception a été levée lors du rendu d'un modèle (« Paramètre « customer_id » pour la route « customer_show » doit correspondre à » [^ /] ++ "(" "donné) pour générer une URL correspondante.").

je peux éviter cela dans une condition $ this-> requestStack-> getCurrentRequest() -> get ('customer_id') pour créer l'enfant que si le paramètre d'itinéraire est disponible.

class MenuBuilder 
{ 


private $factory; 
private $requestStack; 

/** 
* @param FactoryInterface $factory 
* 
* Add any other dependency you need 
*/ 
public function __construct(FactoryInterface $factory,RequestStack $requestStack) 
{ 
    $this->factory = $factory; 
    $this->requestStack = $requestStack; 
} 
public function createMainMenu(array $options) 
{ 

    $menu = $this->factory->createItem('root'); 

    $menu->addChild('storebundle.menu.storehome', array('route' => 'site_homepage')); 
    $menu->addChild('storebundle.menu.adminhome', array('route' => 'lilworks_store_homepage')); 
    $userMenuCat = $menu->addChild('storebundle.menu.cat.user'); 

    $customerMenu = $userMenuCat->addChild('storebundle.menu.customer', array('route' => 'customer_index')); 
    $customerMenu->addChild('storebundle.menu.customer.new', array('route' => 'customer_new')); 
    if($this->requestStack->getCurrentRequest()->get('customer_id')){ 
     $customerMenu->addChild('storebundle.menu.customer.show', array('route' => 'customer_show', 'routeParameters' => array('customer_id' => $this->requestStack->getCurrentRequest()->get('customer_id')))); 
     $customerMenu->addChild('storebundle.menu.customer.edit', array('route' => 'customer_edit', 'routeParameters' => array('customer_id' => $this->requestStack->getCurrentRequest()->get('customer_id')))); 
    } 

    $userMenu = $userMenuCat->addChild('storebundle.menu.user', array('route' => 'user_index')); 
    $userMenu->addChild('storebundle.menu.user.new', array('route' => 'user_new')); 
    if($this->requestStack->getCurrentRequest()->get('user_id')){ 
     #$userMenu->addChild('storebundle.menu.user.show', array('route' => 'user_show', 'routeParameters' => array('user_id' => $this->requestStack->getCurrentRequest()->get('user_id')))); 
     #$userMenu->addChild('storebundle.menu.user.edit', array('route' => 'user_edit', 'routeParameters' => array('user_id' => $this->requestStack->getCurrentRequest()->get('user_id')))); 
    } 

    $sessionMenu = $userMenuCat->addChild('storebundle.menu.session', array('route' => 'session_index')); 
    if($this->requestStack->getCurrentRequest()->get('session_id')){ 
     #$sessionMenu->addChild('storebundle.menu.session.show', array('route' => 'session_show', 'routeParameters' => array('session_id' => $this->requestStack->getCurrentRequest()->get('session_id')))); 
     #$sessionMenu->addChild('storebundle.menu.session.edit', array('route' => 'session_edit', 'routeParameters' => array('session_id' => $this->requestStack->getCurrentRequest()->get('session_id')))); 
    } 


    $orderMenuCat = $menu->addChild('storebundle.menu.cat.order'); 
    $orderMenu = $orderMenuCat->addChild('storebundle.menu.order', array('route' => 'order_index')); 
    $orderMenu->addChild('storebundle.menu.order.new', array('route' => 'order_new')); 
    if($this->requestStack->getCurrentRequest()->get('order_id')){ 
     #$orderMenu->addChild('storebundle.menu.order.show', array('route' => 'order_show', 'routeParameters' => array('order_id' => $this->requestStack->getCurrentRequest()->get('order_id')))); 
     #$orderMenu->addChild('storebundle.menu.order.edit', array('route' => 'order_edit', 'routeParameters' => array('order_id' => $this->requestStack->getCurrentRequest()->get('order_id')))); 
    } 

    $couponMenu = $orderMenuCat->addChild('storebundle.menu.coupon', array('route' => 'coupon_index')); 
    $couponMenu->addChild('storebundle.menu.coupon.new', array('route' => 'coupon_new')); 
    if($this->requestStack->getCurrentRequest()->get('coupon_id')){ 
     #$couponMenu->addChild('storebundle.menu.coupon.show', array('route' => 'coupon_show', 'routeParameters' => array('coupon_id' => $this->requestStack->getCurrentRequest()->get('coupon_id')))); 
     #$couponMenu->addChild('storebundle.menu.coupon.edit', array('route' => 'coupon_edit', 'routeParameters' => array('coupon_id' => $this->requestStack->getCurrentRequest()->get('coupon_id')))); 
    } 
    $depositSaleMenu = $orderMenuCat->addChild('storebundle.menu.depositsale', array('route' => 'coupon_index')); 
    $depositSaleMenu->addChild('storebundle.menu.depositsale.new', array('route' => 'depositSale_new')); 
    if($this->requestStack->getCurrentRequest()->get('depositsale_id')){ 
     #$depositSaleMenu->addChild('storebundle.menu.coupon.show', array('route' => 'depositSale_show', 'routeParameters' => array('depositsale_id' => $this->requestStack->getCurrentRequest()->get('depositsale_id')))); 
     #$depositSaleMenu->addChild('storebundle.menu.coupon.edit', array('route' => 'depositSale_edit', 'routeParameters' => array('depositsale_id' => $this->requestStack->getCurrentRequest()->get('depositsale_id')))); 
    } 
    return $menu; 
} 

Dans tous les exemples, j'ai vu personne n'utiliser cette condition pour construire le menu avec l'itinéraire paramétré. Qu'est-ce que je fais mal?

Répondre

1

Vous ne faites rien de mal. Si vous avez besoin d'informations à partir de la requête, comme un paramètre de l'URL ou le nom d'utilisateur d'un service (par exemple, $this->tokenStorage->getToken()->getUser();), arrangez-vous pour l'obtenir et utilisez-le.

Dans mon code, je l'ai allé chercher l'utilisateur (comme ci-dessus - en supposant qu'il existe) une utilisation à faire un lien:

$menu->addChild('menu.edit_settings', [ 
     'route' => 'ca_profile_update', 
     'routeParameters' => array('username' => $user->getUsernameCanonical()), 
    ]); 

Pour vous, la seule chose que je voudrais particulièrement faire était de obtenir les différents paramètres ('user_id' et ainsi de suite) une fois dans une variable et ensuite l'utiliser, plutôt que de toujours le re-chercher (c'est un peu trop verbeux à mon avis). Cela et juste diviser le service de menu un peu en plus petites fonctions pour le rendre un peu plus facile à comprendre aussi - mais c'est plus de style et de normes de code que la question originale.

$this->addCustomerMenu(
    $userMenuCat, 
    $this->requestStack->getCurrentRequest()->getInt('customer_id', 0) 
); 

public function addCustomerMenu(MenuItem $userMenuCat, int $customer_id): void 
{ 
    $customerMenu = $userMenuCat->addChild('storebundle.menu.customer', array('route' => 'customer_index')); 
    $customerMenu->addChild('storebundle.menu.customer.new', array('route' => 'customer_new')); 
    if ($customer_id){ 
     $customerMenu->addChild('storebundle.menu.customer.show', array('route' => 'customer_show', 'routeParameters' => array('customer_id' => $customer_id))); 
     $customerMenu->addChild('storebundle.menu.customer.edit', array('route' => 'customer_edit', 'routeParameters' => array('customer_id' => $customer_id))); 
    } 
}