我正在尝试创建一个包来管理可以通过配置文件配置的菜单。
所以我在class DependencyInjection\Configuration
中编写了一些配置约束。
所需的配置是必须添加到菜单中的项目数组。每个项目可以有3种不同的类型(link
,link_notification
,widget
)。对于每种类型,项目都需要其他属性(例如route
,label
等)。
配置示例:
menu:
utilities:
- { type: link, icon: icon_name, label: text, route: { name: route_name, params: {} } }
- { type: link_notification, notification: notification_text }
- { type: widget, controller: controller_name }
我被卡住了,因为我找不到如何为每种类型定义不同的数组约束。
我找不到翻译条件的方法:
IF type == "link" THEN scalarNode "icon" IS REQUIRED AND scalarNode "label" IS REQUIRED ...
配置文件如下所示:
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('aiomedia_menu');
$rootNode
->children()
->arrayNode('utilities')
->prototype('array')
->children()
->enumNode('type')
->values(array ('link', 'link_notification', 'widget'))
->isRequired()
->end()
->end()
->end()
->end()
->end();
return $treeBuilder;
}
我在Symfony2文档中看到了方法->ifXXX() [...] ->then()
,但我无法弄清楚如何在这种情况下使用它们。
答案 0 :(得分:1)
它会是这样的:(没有经过测试,但它会给你一些指导方向)
$rootNode
->children()
->arrayNode('utilities')
->prototype('array')
->validation()
->ifTrue(function ($v) {
if (!is_array($v)) {
return true;
}
switch ($v['type']) {
case 'link':
$requiredSettings = array('icon', 'label', 'route');
break;
case 'link_notification':
$requiredSettings = array('notification');
break;
case 'widget':
$requiredSettings = array('controller');
break;
}
foreach ($requiredSettings as $setting) {
if (!array_key_exists($setting, $v)) {
return false;
}
}
return true;
})
->thenInvalid('Missing required options for "%s"')
->end()
->children()
->enumNode('type')
->values(array ('link', 'link_notification', 'widget'))
->isRequired()
->end()
->end()
->end()
->end()
->end();