Symfony2:具有必填字段的条件包配置部分

Symfony2: Conditional bundle configuration sections with required fields

就像标题一样。我希望在我的捆绑包配置中有一个一旦启用的部分——它会有一些必填字段。目前我不知道如何实现这一目标。我尝试了 canBeEnabled() 和 canBeDisabled() 选项,如下所述: http://symfony.com/doc/current/components/config/definition.html#optional-sections 。但没有运气。我的意思是,即使部分被禁用,如果它包含必填字段 - 也会抛出错误。我想要实现的是仅在启用部分的情况下未填充字段时抛出错误。有什么办法可以实现吗?

我的配置验证:

    $rootNode
        ->children()
            ->arrayNode('defaults')->canBeDisabled()
                ->children()
                    ->scalarNode('firewall')->isRequired()->cannotBeEmpty()->end()
                    ->scalarNode('user')->isRequired()->cannotBeEmpty()->end()
                    ->arrayNode('controllers')
                        ->children()
                            ->booleanNode('registration')->defaultTrue()->end()
                        ->end()
                    ->end()
                ->end()
            ->end()

在我的配置中:

mybundle:
    defaults:
        user: default
        firewall: default
        controllers:
            registration: true

我希望能够禁用 "defaults",但如果启用此部分(默认情况下应该是什么):userfirewall 应该明确要求设置。

您的配置树如您所愿。我要做的唯一更改是将 canBeDisabled() 更改为 caBeEnabled()。虽然这只是我的意见,并没有什么区别。我认为您可能对它的工作原理感到困惑。

您的配置:

mybundle:
    defaults:
        user: default
        firewall: default
        controllers:
            registration: true

将使用整棵树进行验证。输出将在 $sonfig['defaults']['enabled'] 处包含一个设置为 true 的额外键。根据您的配置树,userfirewall 都必须包含一个值。

现在,如果您指定 config.yml,例如:

mybundle: ~

defaults 分支中的所有内容都被跳过。结果数组看起来像 $sonfig['defaults']['enabled'] = false。没有默认值被添加到输出。没有什么。 enabled 键是一种快速检测方法。

到 enable/disable 一个分支,您需要重组 config.yml 以便所有参数都在一个键下。类似于(不知道捆绑包的用途,很难猜出合适的名称):

mybundle:
    access:
        defaults:
            user: default
            firewall: default
            controllers:
                registration: true

配置树将如下所示:

$rootNode
->children()
    ->arrayNode('access')
    ->canBeDisabled()
        ->children()
            ->arrayNode('defaults')
                ->children()
                    ->scalarNode('firewall')->isRequired()->cannotBeEmpty()->end()
                    ->scalarNode('user')->isRequired()->cannotBeEmpty()->end()
                    ->arrayNode('controllers')
                        ->children()
                            ->booleanNode('registration')->defaultTrue()->end()
                        ->end()
                    ->end()
                ->end()
            ->end();

现在的配置如下所示:

mybundle:
    access: ~

甚至根本不申报:

mybundle:
    other_non_optional_key: foo

附带说明一下,我不喜欢必须使用额外嵌套级别的想法。当存在必填字段时,我会在 canBeDisabled()consider it a bug。您可以通过将 isRequired() 替换为 defaultValue() 并使用自定义 validate() 方法来完成类似的事情。