Symfony中的配置等于验证配置。
我想用treebuilder验证我的配置。在yml-example中,我给出了一个很好的例子,说明配置树的外观(将来,树将比现在更大)。但要做到这一点,我需要一个创建一个结构。
你能帮助我,创建一个树木建造者吗?我已尝试使用arrayNode和原型,但它无法正常工作。我得到像
“FatalErrorException:Error:在/var/www/menu_bundle/src/my/MenuBundle/DependencyInjection/Configuration.php第29行调用未定义的方法Symfony \ Component \ Config \ Definition \ Builder \ NodeBuilder :: prototype()”
基本理念:
我想生成一个Symfony2-bundle,它以HTML格式创建一个menuStructure。为了生成HTML代码,我需要将yaml-configuration拉入对象结构,这是有效的,但是使用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。 我正在寻找的是一种在treebuilder中重用一个部分(menuItem-:name,route和children)的方法,但到目前为止我发现的一切都无法帮助我...... 其他所有工作,我唯一的问题是,我无法配置Treebuilder,我无法使用$ this-> container-> get('menu.name')从yml中获取配置。这会引发异常:您已请求不存在的服务“menu.name”。
到目前为止,我已尝试使用原型('array')进行一些配置,但phpStorm每次都说,它找不到scalarNode作为原型的子项或 - > prototype() - > children( ) - > scalarNode()..
答案 0 :(得分: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'
答案 1 :(得分:0)
我知道这个问题可以追溯到januari 2014,但是在寻找错误消息的解决方案“调用未定义的方法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()的调用会使您在层次结构中向上一步。
就我自己而言,我不清楚的是,在一个arrayNode定义中,arrayNode()
定义作为底层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();
希望这有助于其他人比我更快地解决问题。