如何动态地将部分附加到Symfony 2配置?

时间:2013-02-01 17:34:22

标签: symfony

my_bundle:
    algorithm: blowfish # One of 'md5', 'blowfish', 'sha256', 'sha512'

此配置由此配置树完成:

// Algorithms and constants to check
$algorithms = array(
    'md5'      => 'CRYPT_MD5',
    'blowfish' => 'CRYPT_BLOWFISH',
    'sha256'   => 'CRYPT_SHA256',
    'sha512'   => 'CRYPT_SHA512',
);

$rootNode
    ->children()
        ->scalarNode('algorithm')
            ->isRequired()
            ->beforeNormalization()
                ->ifString()
                ->then(function($v) { return strtolower($v); })
            ->end()
            ->validate()
                ->ifNotInArray(array_keys($algorithms))
                ->thenInvalid('invalid algorithm.')
            ->end()
            ->validate()
                ->ifTrue(function($v) use($algorithms) {
                    return 1 != @constant($algorithms[$v]);
                })
                ->thenInvalid('algorithm %s is not supported by this system.')
            ->end()
        ->end()
    ->end();

由于每个算法都需要不同的参数,如何根据所选算法动态添加它们作为根节点的子节点?

例如,如果算法是“blowfish”,则应该有一个名为“cost”的标量节点,而如果“sha512”是一个标量节点“rounds”,每个节点都有不同的验证规则。

编辑:我真正需要的是弄清楚当前的算法(如何处理$rootNode?)而不是调用:

$rootNode->append($this->getBlowfishParamsNode());
$rootNode->append($this->getSha256ParamsNode());
$rootNode->append($this->getSha512ParamsNode());

编辑:我想要完成的可能配置:

my_bundle:
    algorithm: blowfish
    cost: 15

另:

my_bundle:
    algorithm: sha512
    rounds: 50000

另一个:

my_bundle:
    algorithm: md5

2 个答案:

答案 0 :(得分:3)

如果ifTrue()的值为algorithm,您可以检查(使用md5)。如果是这种情况,则取消设置包含原始配置值的数组中的blowfishsha256sha513键。

如果algorithmblowfishsha256sha513,您可以使用类似的逻辑。


$rootNode->
    ->beforeNormalization()
        //...
        ->ifTrue(function($v) {
            // $v contains the raw configuration values
            return 'md5' === $v['algorithm'];
        })
        ->then(function($v) {
            unset($v['blowfish']);
            unset($v['sha256']);
            unset($v['sha512']);
            return $v;
        })
        ->end()
        // ...do same logic for the others
    ->end();

你必须使用这样的东西:

my_bundle:
    algorithm: blowfish
    md5: #your params
    blowfish: #will be unset if algorithm is md5 for example
    sha256: #will be unset if algorithm is md5 for example
    sha512: #will be unset if algorithm is md5 for example

如你所说,你可以追加所有这些:

$rootNode->append($this->getMd5ParamsNode());
$rootNode->append($this->getBlowfishParamsNode());
$rootNode->append($this->getSha256ParamsNode());
$rootNode->append($this->getSha512ParamsNode());

修改

还有一个thenUnset()功能。

修改

Doctrine的way of doing it可能会引起人们的兴趣。

答案 1 :(得分:0)

Gremo,也许我在这里走错了路。顺便说一句,谢谢你对我的问题的答复。

这只是一个意见,也许只是一个愚蠢的答案......好吧,我们走了。

对于您的回答,我知道您已经了解/了解bundle extension的工作原理。

也许你可以定义configuring-services-and-setting-parameters

上所见的4个空参数

... 您将根据传入的配置值在扩展类中设置此参数 ...

然后你可以对树进行特定的检查(比如算法是'河豚'然后需要成本)

$rootNode->
    ->beforeNormalization()
        ->ifTrue(function($v) {
            // $v contains the raw configuration values
            // if 'algorithm' blowfish -> cost isRequired
            // or as you said on your question you can call
            // ->append($this->addBlowfishParametersNode())
        })
        ->then(function($v) {
            // maybe some unsetting, but not needed
        })
        ->end()
    ->children()
        // ...
    ->end()
;

选中“Appending Sections

public function addBlowfishParametersNode()
{
    $builder = new TreeBuilder();
    $node = $builder->root('parameters');

    $node
        ->isRequired()
        ->requiresAtLeastOneElement()
        ...
        ...