I have a problem with Symfony4 bundle configuration. I have a configuration class with:
$rootNode
->children()
->arrayNode('mapping')
->useAttributeAsKey('code')
->prototype('scalar')->end()
->defaultValue(['default' => 'test'])
->end()
.....
->end();
This returns a default configuration like:
array(1) {
["default"]=> string(4) "test"
}
But when I add a configuration file:
bundle:
mapping:
test: newvalue
test2: newvalue2
Im getting a config:
array(2) {
["test"]=> string(8) "newvalue"
["test2"]=> string(9) "newvalue2"
}
But I expect to merge these two configs to get:
array(3) {
["default"]=> string(4) "test"
["test"]=> string(8) "newvalue"
["test2"]=> string(9) "newvalue2"
}
How can I set this defaults to be merged with provided configurations? Of course I want to let "default" config to be overridden, but by deafult to be merged.
I cant find any solution on docs https://symfony.com/doc/current/components/config/definition.html#array-node-options
Please help :)
If I understood correctly you want the default
entry to be always defined. Applicaions will be able to overwrite the default value DEFAULT
of default
key.
Ok, there are two solutions :
A bad solution
$rootNode = $treeBuilder->getRootNode()
->children()
->arrayNode('mapping')
->useAttributeAsKey('code')
->prototype('scalar')->end()
->beforeNormalization()
->ifArray()
->then(function ($mapping) {
return $mapping + ['default' => 'DEFAULT'];
})
->end()
->end();
If default key is not defined it will be added along with default DEFAULT
value. It will function for ONE configuration file parsed. BUT you will get the problem if you have two and more configuraion files:
# config.yml
mapping:
some: value
default: MY_DEVELOPMENT_DEFAULT
# prod/config.yml
mapping:
some: value_prod
You will have :
['some' => 'value_prod', 'default' => 'DEFAULT']
This is wrong. Default value replaces MY_DEVELOPMENT_DEFAULT
because it was added to prod/config.yml
and merged with config.yml
.
Unfortunately, tree builder doesn't permit to define callback after merge.
A good solution
You can add your default entries after the configuraion values are merged (e.g. in compiler passes).