Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically append sections to Symfony 2 configuration?

Tags:

symfony

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

This configuration is done by this configuration tree:

// 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();

Since each algorithm requires different parameters, how can I dynamically add them as children of the root node, base on the selected algorithm?

For example, if algorithm is "blowfish" there should be a scalar node named "cost", while if "sha512" a scalar node "rounds", each with different validation rules.

EDIT: what I really need is figure out the current algorithm (how to do with $rootNode?) and than call on of:

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

EDIT: possible configurations I'd like to accomplish:

my_bundle:
    algorithm: blowfish
    cost: 15

Another:

my_bundle:
    algorithm: sha512
    rounds: 50000

And another:

my_bundle:
    algorithm: md5
like image 693
gremo Avatar asked Feb 01 '13 17:02

gremo


1 Answers

You could check (using ifTrue()) if the value of algorithm is md5. If this is the case, you unset the blowfish, sha256, sha513 keys in the array containing the raw config values.

You can then use a similar logic if algorithm is blowfish, sha256 or sha513.


$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();

You'd have to use something like this:

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

As you mention, you can then append all of them:

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

EDIT

There is also a thenUnset() function.

EDIT

Doctrine's way of doing it might be of interest here.

like image 51
Mick Avatar answered Oct 10 '22 19:10

Mick