Pregunta

Configurar en Symfony es igual a validar la configuración.Quiero validar mi configuración con treebuilder.En el ejemplo de yml, doy un buen ejemplo de cómo se verá el árbol de configuración (en el futuro, el árbol será incluso más grande que ahora).Pero para hacer esto, necesito crear una estructura.
Ahora ¿podrías ayudarme a crear el constructor de árboles?Probé todo con arrayNode y prototipos, pero no funcionó.Recibo excepciones como

"Excepción de error fatal:Error:Llamada al método no definido Symfony\Component\Config\Definition\Builder odeBuilder::prototype() en /var/www/menu_bundle/src/my/MenuBundle/DependencyInjection/Configuration.php línea 29 "


Idea básica:

Quiero generar un paquete Symfony2, que crea una estructura de menú en HTML.Para generar el código HTML, necesito incorporar la configuración de yaml a una estructura de objeto, esto funciona, pero la validación con Symfony no funciona...


Aquí hay un ejemplo rápido de cómo debería verse 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

Ahora quiero configurar Treebuilder en Symfony2, pero no funciona.

Después de intentarlo varias veces, esta es mi última versión:

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

He creado los objetos para Menú y MenuItems.Todo funciona hasta ahora, pero no puedo configurar el generador de árboles.Lo que estoy buscando es una forma de reutilizar una pieza (menuItem-:nombre, ruta y niños) en el constructor de árboles, pero todo lo que encontré hasta ahora no pudo ayudarme...Todo lo demás funciona, mi único problema es que no puedo configurar Treebuilder y no puedo sacar la configuración del yml con $this->container->get('menu.name').Esto arroja una excepción:Ha solicitado un servicio "menú.nombre" inexistente.

Hasta ahora, he probado algo de configuración con el prototipo ('array'), pero phpStorm dice cada vez que no puede encontrar un scalarNode como hijo del prototipo o de ->prototype()->children()->scalarNode( )..

¿Fue útil?

Solución

Sé que esta pregunta data de enero de 2014, sin embargo, cuando buscaba una solución al mensaje de error "Llamar a un método no definido Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition::arrayNode()", apareció esta pregunta de StackOverflow en los resultados de búsqueda. .

La respuesta aceptada en realidad no menciona el motivo del mensaje de error.

El ejemplo dado por el cartel original es el siguiente:

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

Esto es incorrecto porque cada nodo debe terminar con un end() llamar.Como dice la [documentación][1]:

En general:Después de definir un nodo, una llamada a end() le lleva un paso hacia arriba en la jerarquía.

En mi propio caso, lo que no me quedó claro fue el hecho de que en una definición de arrayNode tanto el arrayNode() definición como subyacente children() Hay que poner fin a la definición.

Entonces el ejemplo anterior sería correcto de la siguiente manera:

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

Con suerte, esto ayudará a otros a solucionar el problema más rápido que yo.

Otros consejos

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'
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top