配置树:添加条件验证

时间:2013-11-03 11:12:10

标签: symfony configuration tree

我正在尝试创建一个包来管理可以通过配置文件配置的菜单。

所以我在class DependencyInjection\Configuration中编写了一些配置约束。

所需的配置是必须添加到菜单中的项目数组。每个项目可以有3种不同的类型(linklink_notificationwidget)。对于每种类型,项目都需要其他属性(例如routelabel等)。

配置示例:

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(),但我无法弄清楚如何在这种情况下使用它们。

1 个答案:

答案 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();