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

1.3k views Asked by At

Using Symfony 3.3.12, i'm trying to use 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

1

There are 1 answers

0
Jack Skeletron On BEST ANSWER

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. Just a big mistery to me.

service.yml

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

And this is MenuBuilder.php

class MenuBuilder {

    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 createSidebarMenu(array $options) {
        # code
    }
}