2

Symfony 中的配置等同于验证配置。我想用 treebuilder 验证我的配置。在 yml-example 中,我给出了一个配置树的外观示例(将来,树会比现在更大)。但要做到这一点,我需要创建一个结构。
现在你能帮我创建树生成器吗?我已经用 arrayNode 和原型尝试了一切,但它不起作用。我得到像这样的例外

“FatalErrorException:错误:调用 /var/www/menu_bundle/src/my/MenuBundle/DependencyInjection/Configuration.php 第 29 行中的未定义方法 Symfony\Component\Config\Definition\Builder\NodeBuilder::prototype()”


基本理念:

我想生成一个 Symfony2-bundle,它在 HTML 中创建一个 menuStructure。为了生成 HTML 代码,我需要将 yaml 配置拉入对象结构中,这可行,但使用 symfony 进行验证不起作用...


下面是一个关于 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

现在我想在 Symfony2 中配置 Treebuilder,但它不起作用..

经过几次尝试,这是我的最后一个版本:

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

我已经为 Menu 和 MenuItems 构建了对象。到目前为止一切正常,但我无法配置treebuilder。我正在寻找的是一种在树生成器中重用部分(menuItem-:名称,路线和子项)的方法,但是到目前为止我发现的所有内容都无法帮助我......其他一切都有效,我唯一的问题也就是说,我无法配置 Treebuilder,也无法使用 $this->container->get('menu.name') 从 yml 中获取配置。这会引发异常:您请求了一个不存在的服务“menu.name”。

到目前为止,我已经尝试了一些带有原型('array')的配置,但是 phpStorm 每次都说,它找不到一个 scalarNode 作为原型或 ->prototype()->children()->scalarNode( )..

4

2 回答 2

1

你可以做的是这样配置你的rootNode:

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

然后,您想将此变量传递给服务。非常简单的类:

class AdminMenu
{

    protected $menu;

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

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


}

在你的 services.xml 中

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

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

在您的 bundleAdminExtension 类中

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

最后,在您想要的任何控制器中:

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

就这样 :)

编辑:这是我的配置的样子

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'
于 2014-04-07T10:31:52.810 回答
0

我知道这个问题可以追溯到 2014 年 1 月,但是在寻找错误消息“调用未定义方法 Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition::arrayNode()”的解决方案时,这个 StackOverflow 问题出现在搜索结果中.

接受的答案实际上并未提及错误消息的原因。

原发帖人给出的例子如下:

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

这是不正确的,因为每个节点都必须以end()调用结束。正如 [文档] [1] 所述:

一般来说:在定义一个节点之后,调用 end() 会使您在层次结构中更上一层楼。

在我自己的情况下,我不清楚的是,在 arrayNodearrayNode()定义中,作为基础children()定义的定义都必须结束。

所以上面的例子是正确的,如下所示:

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

希望这将帮助其他人比我更快地解决问题。

于 2016-11-17T13:08:39.717 回答