Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Configuration] Use of source keys as result keys for prototype nodes #12304

Closed
lividgreen opened this issue Oct 23, 2014 · 2 comments
Closed

Comments

@lividgreen
Copy link

Here is the code example when source keys are ignored in processed configuration:

<?php
$processor = new \Symfony\Component\Config\Definition\Processor();

$treeBuilder = new \Symfony\Component\Config\Definition\Builder\TreeBuilder();
$root = $treeBuilder->root('my_config');
$root->prototype('scalar')->end();

$result = $processor->process($treeBuilder->buildTree(), array(array('one' => '1', 'two' => '2')));
var_dump($result); // keys "one" and "two" are ignored

Result:

array(2) {
  [0] =>
  string(1) "1"
  [1] =>
  string(1) "2"
}

Here is another example that adds source keys to the result:

<?php
$processor = new \Symfony\Component\Config\Definition\Processor();

$treeBuilder = new \Symfony\Component\Config\Definition\Builder\TreeBuilder();
$root = $treeBuilder->root('my_config');
$root
    ->useAttributeAsKey('whatever') // magic
    ->prototype('scalar')
    ->end();

$result = $processor->process($treeBuilder->buildTree(), array(array('one' => '1', 'two' => '2')));
var_dump($result);

Result:

array(2) {
  'one' =>
  string(1) "1"
  'two' =>
  string(1) "2"
}

This also affects merging:

<?php
$processor = new \Symfony\Component\Config\Definition\Processor();

$treeBuilder = new \Symfony\Component\Config\Definition\Builder\TreeBuilder();
$root = $treeBuilder->root('my_config');
$root
    ->useAttributeAsKey('the_key') // magic
    ->prototype('array')
        ->children()
            ->scalarNode('the_key')->end()
            ->scalarNode('the_value')->end()
        ->end()
    ->end();

$config1 = array(
    array('the_key' => 'key1', 'the_value' => 'value1'),
    array('the_key' => 'key2', 'the_value' => 'value2'),
);
$config2 = array(
    'key1' => array('the_value' => 'value3'), // 'the_key' is not present
);

$result = $processor->process($treeBuilder->buildTree(), array($config1, $config2));
var_dump($result);

Result:

array(2) {
  'key1' =>
  array(1) {
    'the_value' =>
    string(6) "value3"
  }
  'key2' =>
  array(1) {
    'the_value' =>
    string(6) "value2"
  }
}

This "feature" is not documented and looks like a magic. I wish there was documented way to preserve keys of prototyped values.

@stof
Copy link
Member

stof commented Nov 21, 2014

This is the intended way to preserve keys. Calling ->useAttributeAsKey() will mark the array node as being a map rather than being a list. Maps and lists will be processed differently.
The name of the method is related to the fact that in XML, the key of the map will be stored in an attribute (due to the XML format), and we need to know the name of this attribute.

I agree that the documentation about it could explain it better. Please open an issue on the https://github.com/symfony/symfony-docs/issues for that.

@xabbuh
Copy link
Member

xabbuh commented Nov 21, 2014

see symfony/symfony-docs#4509

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants