Domanda

La configurazione in Symfony equivale a convalidare la configurazione.Voglio convalidare la mia configurazione con il treebuilder.Nell'esempio yml, fornisco un esempio di come apparirà l'albero di configurazione (in futuro, l'albero sarà ancora più grande di adesso).Ma per fare questo, ho bisogno di creare una struttura.
Ora potresti aiutarmi a creare il treebuilder?Ho provato di tutto con arrayNode e prototipi, ma non funzionerà.Ottengo eccezioni come

"FatalErrorException:Errore:Chiamata al metodo non definito Symfony\Component\Config\Definition\Builder odeBuilder::prototype() nella riga /var/www/menu_bundle/src/my/MenuBundle/DependencyInjection/Configuration.php 29 "


Idea di base:

Voglio generare un bundle Symfony2, che crea una struttura di menu in HTML.Per generare il codice HTML, devo inserire la configurazione yaml in una struttura a oggetti, funziona, ma la convalida con symfony non funziona...


Ecco un rapido esempio di come dovrebbe apparire 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

Ora voglio configurare il Treebuilder in Symfony2, ma non funzionerà..

Dopo alcuni tentativi, questa è la mia ultima versione:

    $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();

Ho creato gli oggetti per Menu e MenuItems.Finora funziona tutto, ma non riesco a configurare il treebuilder.Quello che sto cercando è un modo per riutilizzare una parte (menuItem-:nome, percorso e figli) nel treebuilder, ma tutto quello che ho trovato finora, non mi ha aiutato...Tutto il resto funziona, il mio unico problema è che non riesco a configurare il Treebuilder e non riesco a estrarre la configurazione da yml con $this->container->get('menu.name').Questo genera un'eccezione:Hai richiesto un servizio inesistente "menu.name".

Finora ho provato alcune configurazioni con prototipo('array'), ma phpStorm dice ogni volta che non riesce a trovare uno scalarNode come figlio di prototipo o di ->prototipo()->bambini()->scalarNode( )..

È stato utile?

Soluzione

So che questa domanda risale a gennaio 2014, tuttavia quando cercavo una soluzione al messaggio di errore "Chiama al metodo non definito Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition::arrayNode()" questa domanda StackOverflow è apparsa nei risultati della ricerca .

La risposta accettata in realtà non menziona il motivo del messaggio di errore.

L'esempio fornito dal poster originale è il seguente:

$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();

Questo non è corretto perché ogni nodo deve terminare con un end() chiamata.Come afferma la [documentazione] [1]:

Generalmente:dopo aver definito un nodo, una chiamata a end() ti porta un passo avanti nella gerarchia.

Nel mio caso, ciò che non mi era chiaro era il fatto che in una definizione arrayNode sia il file arrayNode() definizione come sottostante children() la definizione deve essere terminata.

Quindi l'esempio sopra sarebbe corretto come segue:

$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();

Spero che questo aiuti gli altri a risolvere il problema più velocemente di me.

Altri suggerimenti

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'
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top