KnpLabs / KnpMenuBundle

Object Oriented menus for your Symfony project.

Home Page:http://knplabs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Argument 1 passed to Builder::__construct() must implement interface Knp\Menu\FactoryInterface, none given

LeandroLuccerini opened this issue · comments

Hi,
using Symfony 3.3.12, i'm trying to set my menu builder as a service, this is configured in AppBundle/Resources/config/services.yml and imported in main config.yml as

imports:
   - { resource: "@AppBundle/Resources/config/services.yml" }

services.yml

 ##########################################################################
 # Menu Section   
 ##########################################################################
 AppBundle\Menu\Builder:
     arguments: 
         $factory: '@knp_menu.factory'
         $doctrine: '@doctrine'
         $token: '@security.token_storage'
     public: true
     tags:
         - { name: knp_menu.menu_builder, method: sidebarMenu, alias: sidebar }

But i get this error when renderd as

{{ knp_menu_render('sidebar', {'template': 'Menu/knp_sidebar_menu.html.twig', 'allow_safe_labels': true, 'currentClass':'active'}) }}

Argument 1 passed to Builder::__construct() must implement interface Knp\Menu\FactoryInterface, none given, called in /home/demousr/app/vendor/knplabs/knp-menu-bundle/Provider/BuilderAliasProvider.php on line 121

This is my builder

namespace AppBundle\Menu;

use \Knp\Menu\FactoryInterface;
use \AppBundle\Menu\Loader\NodeLoader;
use \Doctrine\Bundle\DoctrineBundle\Registry;
use \Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;

class Builder {

    private $factory;
    private $doctrine;
    private $token;

    public function __construct(FactoryInterface $factory, Registry $doctrine, TokenStorage $token) {
        $this->factory = $factory;
        $this->doctrine = $doctrine;
        $this->token = $token->getToken();
    }

    public function sidebarMenu(array $options) {

        $menu = $this->factory->createItem('root');
        $nodeLoader = new NodeLoader($this->factory, $this->token);
        
        $menu->setChildrenAttribute('class', 'nav nav-sidebar');
        
        $em = $this->doctrine->getManager();
        $tree = $em->getRepository('AppBundle:Menu\Menu')->findOneByMenu('main');
        $roots = $em->getRepository('AppBundle:Menu\MenuItem')->getRootNodesByTree($tree);

        foreach($roots as $root){
            
            $item = $nodeLoader->load($root);
            
            if(null !== $item){
                $menu->addChild($item);
            }
        }
        
        return $menu;
    }

}

I can't find where i'm wrong

I've followed documentation but it seems like i'm using the wrong tag.

looking at

protected function getBuilder($bundleName, $className)
it seems you end up in the wrong place as that part does autodiscover your builder and it can't be a service.

did you look at https://symfony.com/doc/master/bundles/KnpMenuBundle/menu_builder_service.html ? that should explain how to configure your builder as service.

i've just changed the class name in MenuBuilder and the method to createSidebarMenu, and changed the service id with new class name and now it works.

great!