Question

La configuration dans Symfony équivaut à valider la configuration.Je souhaite valider ma configuration avec le treebuilder.Dans l'exemple yml, je donne un bon exemple de ce à quoi ressemblera l'arbre de configuration (à l'avenir, l'arbre sera encore plus grand qu'aujourd'hui).Mais pour ce faire, j’ai besoin de créer une structure.
Maintenant, pourriez-vous m'aider à créer le treebuilder ?J'ai tout essayé avec arrayNode et les prototypes, mais ça ne marchera pas.Je reçois des exceptions comme

"FatalErrorException :Erreur:Appel à la méthode non définie Symfony\Component\Config\Definition\Builder odeBuilder::prototype() dans /var/www/menu_bundle/src/my/MenuBundle/DependencyInjection/Configuration.php ligne 29 "


Idée de base :

Je souhaite générer un bundle Symfony2, qui crée un menuStructure en HTML.Pour générer le code HTML, je dois extraire la configuration yaml dans une structure d'objet, cela fonctionne, mais la validation avec symfony ne fonctionne pas...


Voici un exemple rapide de ce à quoi devrait ressembler le fichier menu.yml :

my_menu_structure:
    menu:
        name: test
        cssClass: blubb
        children:
            child:
                name: item1
                route: route1
                position: 0
                  child:
                    name: item11
                    route: route11
                    position: 0
              child:
                  name: item2
                  route: route2
                  position: 1

Maintenant, je veux configurer Treebuilder dans Symfony2, mais cela ne fonctionnera pas.

Après plusieurs essais, voici ma dernière version :

    $treeBuilder = new TreeBuilder();
    $rootNode = $treeBuilder->root('my_menu');
        $rootNode
            ->children()
            ->arrayNode('menu')
            ->scalarNode('cssClass')
            ->defaultValue(array())
            ->prototype('array')
                ->scalarNode('name')
                ->scalarNode('route')
                ->scalarNode('Position')
                ->prototype('array')

        ->end()
        ->end()
        ->end();

J'ai construit les objets pour Menu et MenuItems.Tout fonctionne jusqu'à présent, mais je n'arrive pas à configurer le treebuilder.Ce que je recherche, c'est un moyen de réutiliser une pièce (menuItem- :nom, itinéraire et enfants) dans le treebuilder, mais tout ce que j'ai trouvé jusqu'à présent n'a pas pu m'aider...Tout le reste fonctionne, mon seul problème est que je ne peux pas configurer Treebuilder et que je ne peux pas extraire la configuration du yml avec $this->container->get('menu.name').Cela lève une exception :Vous avez demandé un service "menu.name" inexistant.

Jusqu'à présent, j'ai essayé une configuration avec prototype('array'), mais phpStorm dit à chaque fois qu'il ne trouve pas de scalarNode en tant qu'enfant du prototype ou de ->prototype()->children()->scalarNode( )..

Était-ce utile?

La solution

Je sais que cette question date de janvier 2014, mais lorsque je cherchais une solution au message d'erreur "Appel à la méthode non définie Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition::arrayNode()", cette question StackOverflow est apparue dans les résultats de la recherche. .

La réponse acceptée ne mentionne pas réellement la raison du message d'erreur.

L'exemple donné par l'affiche originale est le suivant :

$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('my_menu');
$rootNode
        ->children()
        ->arrayNode('menu')
        ->scalarNode('cssClass')
        ->defaultValue(array())
        ->prototype('array')
            ->scalarNode('name')
            ->scalarNode('route')
            ->scalarNode('Position')
            ->prototype('array')

    ->end()
    ->end()
    ->end();

Ceci est incorrect car chaque nœud doit se terminer par un end() appel.Comme l'indique la [documentation][1] :

En général:après avoir défini un nœud, un appel à end() vous fait monter d'un cran dans la hiérarchie.

Dans mon propre cas, ce qui n'était pas clair pour moi, c'était le fait que dans une définition arrayNode, les deux arrayNode() définition comme sous-jacent children() la définition doit être terminée.

L'exemple ci-dessus serait donc correct comme suit :

$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('my_menu');
$rootNode
    ->children()
        ->scalarNode('cssClass')->end()
        ->arrayNode('menu')
            ->prototype('array')
                ->scalarNode('name')->end()
                ->scalarNode('route')->end()
                ->scalarNode('Position')->end()
            ->end()
        ->end()
    ->end()
->end();

J'espère que cela aidera d'autres à résoudre le problème plus rapidement que moi.

Autres conseils

what you can do is to configure your rootNode this way:

    $rootNode
        ->children()
            ->arrayNode('menu')
            ->isRequired()
            ->prototype('array')
                ->children()
                ->scalarNode('label')->isRequired()->end()
                ->scalarNode('class')->end() // I added an optional class parameter
                //others parameters
                    ->arrayNode('sub_menu')
                        ->prototype('array')
                        ->children()
                            ->scalarNode('label')->isRequired()->end()
                            ->scalarNode('route')->end()
                            ->scalarNode('class')->end()
                            // add as many parameters as you want for your children
                        ->end()
                    ->end()
                ->end()
            ->end()
            ->end()
        ->end();

Then you want to pass this variable to a service. Very simple class :

class AdminMenu
{

    protected $menu;

    public function setMenu($menu)
    {
        $this->menu = $menu;
    }

    public function getMenu()
    {
        return $this->menu;
    }


}

In you services.xml

    <parameter key="wf.admin_menu.class">Acme\AdminBundle\Library\AdminMenu</parameter>

    <service id="wf.admin_menu" class="%wf.admin_menu.class%">
    </service>

In your bundleAdminExtension class

    $myServiceDefintion = $container->getDefinition('wf.admin_menu');
    $myServiceDefintion->addMethodCall('setMenu', array($config['menu']));

Finally, in any controller you want:

 $menu = $this->container->get('wf.admin_menu');

That's all :)

Edit : Here's what my config looks like

my_bundle_admin:
  menu:
    unique_key:
      label : 'Level1-1'
      class : ''
      sub_menu:
        sub_unique_key1:
          label: 'Level2-1'
          route: 'my_route'
        sub_unique_key2:
          label: 'Level2-2'
          route: 'my_route'
    unique_key_2:
      label : 'Level1-2'
      sub_menu :
        sub_unique_key1:
          label : 'Level2-1'
          route : 'my_route'
        sub_unique_key2:
          label : 'Level2-2'
          route : 'my_route'
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top