Tableaux en entrée:
array( 'foo' => 'bar', 'bar' => array('some', 'awesome', 'thing'), 'baz' => array('first' => true, 'second' => true), ) array( 'foo' => 'baz', 'bar' => array('other', 'stuff'), 'baz' => array('first' => false), )
Résultat attendu:
array( 'foo' => 'baz', 'bar' => array('some', 'awesome', 'thing', 'other', 'stuff'), 'baz' => array('first' => false, 'second' => true), )
$config = array_merge( array( 'foo' => 'bar', 'bar' => array('some', 'awesome', 'thing'), 'baz' => array('first' => true, 'second' => true), ), array( 'foo' => 'baz', 'bar' => array('other', 'stuff'), 'baz' => array('first' => false), ) );
array
'foo' => string 'baz' (length=3)
'bar' =>
array
0 => string 'other' (length=5)
1 => string 'stuff' (length=5)
'baz' =>
array
'first' => boolean false
'second' => boolean true
Remarque: array_replace fait la même chose pour un tableau associatif.
Nos configurations sont souvent sur plusieurs niveaux.
Premier essai: array_merge_recursive
$config = array_merge_recursive( array( 'foo' => 'bar', 'bar' => array('some', 'thing'), 'baz' => array('first' => true, 'second' => true), ), array( 'foo' => 'baz', 'bar' => array('other', 'awesome', 'stuff'), 'baz' => array('first' => false), ) );
array
'foo' =>
array
0 => string 'bar' (length=3)
1 => string 'baz' (length=3)
'bar' =>
array
0 => string 'some' (length=4)
1 => string 'awesome' (length=7)
2 => string 'thing' (length=5)
3 => string 'other' (length=5)
4 => string 'stuff' (length=5)
'baz' =>
array
'first' =>
array
0 => boolean true
1 => boolean false
'second' => boolean true
Nos configurations sont souvent sur plusieurs niveaux.
Deuxième essai: array_replace_recursive
$config = array_replace_recursive( array( 'foo' => 'bar', 'bar' => array('some', 'awesome', 'thing'), 'baz' => array('first' => true, 'second' => true), ), array( 'foo' => 'baz', 'bar' => array('other', 'stuff'), 'baz' => array('first' => false, 'second' => true), ) );
array
'foo' => string 'baz' (length=3)
'bar' =>
array
0 => string 'other' (length=5)
1 => string 'stuff' (length=5)
2 => string 'thing' (length=5)
'baz' =>
array
'first' => boolean false
'second' => boolean true
$treeBuilder = new \Symfony\Component\Config\Definition\Builder\TreeBuilder(); $root = $tb->root('my_config'); $root ->children() ->scalarNode('foo')->end() ->arrayNode('bar') ->prototype('scalar')->end() ->end() ->arrayNode('baz') ->children() ->booleanNode('first')->end() ->booleanNode('second')->end() ->end() ->end() ->end();
$input = array( array( 'foo' => 'bar', 'bar' => array('some', 'awesome', 'thing'), 'baz' => array('first' => true, 'second' => true), ), array( 'foo' => 'baz', 'bar' => array('other', 'stuff'), 'baz' => array('first' => false), ), ); $processor = new \Symfony\Component\Config\Definition\Processor(); $tree = $treeBuilder->buildTree(); $config = $processor->process($tree, $input);
array
'foo' => string 'baz' (length=3)
'bar' =>
array
0 => string 'some' (length=4)
1 => string 'awesome' (length=7)
2 => string 'thing' (length=5)
3 => string 'other' (length=5)
4 => string 'stuff' (length=5)
'baz' =>
array
'first' => boolean false
'second' => boolean true
$tb = new TreeBuilder(); $root = $tb->root('my_config'); $root ->children() ->scalarNode('foo')->defaultValue('baz')->end() ->arrayNode('bar') ->defaultValue(array('some', 'awesome', 'thing', 'other', 'stuff')) ->prototype('scalar')->end() ->end() ->arrayNode('baz') ->addDefaultsIfNotSet() ->children() ->booleanNode('first')->defaultFalse()->end() ->booleanNode('second')->defaultTrue()->end() ->end() ->end() ->end();
Remarque: Pour le noeud prototypé, la valeur par défault n'est appliquée que s'il n'est jamais ajouté.
Pour ajouter des éléments présents quelque soit l'entrée, il faut rajouter un tableau dans les entrées.
Tableaux en entrée:
$input = array( array( 'foo' => 'bar', 'baz' => array('first' => true, 'second' => true, 'third' => array('foo' => true)), ), array( 'foo' => 'baz', 'baz' => array('first' => array(true, false), 'third' => false), ), );
Résultat attendu:
array( 'foo' => 'baz', 'baz' => array( 'first' => array(true, true, false), 'second' => true, 'third' => array('foo' => true, 'default' => false), ), )
$treeBuilder = new \Symfony\Component\Config\Definition\Builder\TreeBuilder(); $root = $tb->root('my_config'); $root ->children() ->arrayNode('baz') ->children() ->arrayNode('first') ->beforeNormalization() ->ifTrue(function($v) {return is_scalar($v);}) ->then(function($v) {return array($v);}) ->end() ->prototype('boolean')->end() ->end() ->booleanNode('second')->end() ->arrayNode('third') ->useAttributeAsKey('key') ->beforeNormalization() ->ifTrue(function($v) {return is_scalar($v);}) ->then(function($v) {return array('default' => $v);}) ->end() ->prototype('boolean')->end() ->end() ->end() ->end() ->scalarNode('foo')->end() ->end();
array
'baz' =>
array
'first' =>
array
0 => boolean true
1 => boolean true
2 => boolean false
'second' => boolean true
'third' =>
array
'foo' => boolean true
'default' => boolean false
'foo' => string 'baz' (length=3)
$root ->children() ->scalarNode('foo')->defaultValue('baz')->cannotBeEmpty()->end() ->scalarNode('can be defined only once')->cannotBeOverwritten()->isRequired()->end() ->arrayNode('bar') ->requiresAtLeastOneElement() ->defaultValue(array('some')) ->prototype('scalar')->end() ->end() ->arrayNode('baz') ->children() ->booleanNode('first')->isRequired()->end() ->booleanNode('second')->defaultTrue()->end() ->end() ->end() ->end();
$input = array( array('foo' => ''), );
Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
The path "my_config.foo" cannot contain an empty value, but got "".
$root ->children() ->scalarNode('foo')->defaultValue('baz')->cannotBeEmpty()->end() ->scalarNode('can be defined only once')->cannotBeOverwritten()->isRequired()->end() ->arrayNode('bar') ->requiresAtLeastOneElement() ->defaultValue(array('some')) ->prototype('scalar')->end() ->end() ->arrayNode('baz') ->children() ->booleanNode('first')->isRequired()->end() ->booleanNode('second')->defaultTrue()->end() ->end() ->end() ->end();
$input = array( );
Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
The child node "can be defined only once" at path "my_config" must be
configured.
$root ->children() ->scalarNode('foo')->defaultValue('baz')->cannotBeEmpty()->end() ->scalarNode('can be defined only once')->cannotBeOverwritten()->isRequired()->end() ->arrayNode('bar') ->requiresAtLeastOneElement() ->defaultValue(array('some')) ->prototype('scalar')->end() ->end() ->arrayNode('baz') ->children() ->booleanNode('first')->isRequired()->end() ->booleanNode('second')->defaultTrue()->end() ->end() ->end() ->end();
$input = array( array('can be defined only once' => 3), array('can be defined only once' => 4), );
Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException
Configuration path "my_config.can be defined only once" cannot be
overwritten. You have to define all options for this path, and any of
its sub-paths in one configuration section.
$root ->children() ->scalarNode('foo')->defaultValue('baz')->cannotBeEmpty()->end() ->scalarNode('can be defined only once')->cannotBeOverwritten()->isRequired()->end() ->arrayNode('bar') ->requiresAtLeastOneElement() ->defaultValue(array('some')) ->prototype('scalar')->end() ->end() ->arrayNode('baz') ->children() ->booleanNode('first')->isRequired()->end() ->booleanNode('second')->defaultTrue()->end() ->end() ->end() ->end();
$input = array( array('can be defined only once' => 4), array('bar' => array()), );
Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
The path "my_config.bar" should have at least 1 element(s) defined.
$root ->children() ->scalarNode('foo')->defaultValue('baz')->cannotBeEmpty()->end() ->scalarNode('can be defined only once')->cannotBeOverwritten()->isRequired()->end() ->arrayNode('bar') ->requiresAtLeastOneElement() ->defaultValue(array('some')) ->prototype('scalar')->end() ->end() ->arrayNode('baz') ->children() ->booleanNode('first')->isRequired()->end() ->booleanNode('second')->defaultTrue()->end() ->end() ->end() ->end();
$input = array( array('foo' => 'bar', 'can be defined only once' => 4), array('baz' => array('second' => false)), );
Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
The child node "first" at path "my_config.baz" must be configured.
$root ->children() ->scalarNode('foo')->defaultValue('baz')->cannotBeEmpty()->end() ->scalarNode('can be defined only once')->cannotBeOverwritten()->isRequired()->end() ->arrayNode('bar') ->requiresAtLeastOneElement() ->defaultValue(array('some')) ->prototype('scalar')->end() ->end() ->arrayNode('baz') ->children() ->booleanNode('first')->isRequired()->end() ->booleanNode('second')->defaultTrue()->end() ->end() ->end() ->end();
$input = array( array('can be defined only once' => 4), array('baz' => array('first' => false)), );
Configuration acceptée
$root ->children() ->scalarNode('foo') ->defaultValue('pouet') ->validate() ->ifNotInArray(array('foo', 'bar', 'baz')) ->thenInvalid('The value %s is not allowed') ->end() ->validate() ->ifTrue(function($v) {return 'baz' === $v;}) ->then(function($v) {return 'hello ' . $v;}) ->end() ->end() ->end();
$config = array_merge_recursive( array( 'baz' => array('first' => true, 'second' => true), ), array( 'baz' => array('first' => false), ) );
array
'baz' =>
array
'first' =>
array
0 => boolean true
1 => boolean false
'second' => boolean true
function getNode($name) { $tb = new TreeBuilder(); return $tb->root($name) ->beforeNormalization() ->ifTrue(function($v) {return is_scalar($v);}) ->then(function($v) {return array($v);}) ->end() ->prototype('boolean')->end() ->validate() ->ifTrue(function($v) {return 1 === count($v);}) ->then(function($v) {return current($v);}) ->end(); } $root ->children() ->arrayNode('baz') ->append(getNode('first')) ->append(getNode('second')) ->end() ->end();
array
'baz' =>
array
'first' =>
array
0 => boolean true
1 => boolean false
'second' => boolean true