Allowing key-value pairs in Symfony 2 Bundle semantic configuration

gremo picture gremo · Jun 7, 2012 · Viewed 8.5k times · Source

Basically i'd like to allow an arbitrary (but not empty) number of key-value pairs in my configuration, under billings node, that is define an associative array.

I've this in my Configurator.php (part of):

->arrayNode('billings')
    ->isRequired()
    ->requiresAtLeastOneElement()
    ->prototype('scalar')
    ->end()
->end()

And then, in my config.yml:

my_bundle:
    billings:
        monthly : Monthly
        bimonthly : Bimonthly

However, outputting $config:

class MyBundleExtension extends Extension
{
    /**
     * {@inheritDoc}
     */
    public function load(array $configs, ContainerBuilder $container)
    {
        $loader = new Loader\YamlFileLoader($container,
            new FileLocator(__DIR__.'/../Resources/config'));
        $loader->load('services.yml');

        $processor     = new Processor();
        $configuration = new Configuration();

        $config = $processor->processConfiguration($configuration, $configs);

        $container->setParameter('my_bundle.billings', $config['billings']);

        var_dump($config);
        die();
    }

}

... what i get is array index by numbers, not an associative one:

 'billings' => 
     array (size=2)
         0 => string 'Monthly' (length=7)
         1 => string 'Bimonthly' (length=9)

Out of curiosity (and if this can help), i'm trying to inject this array as a service parameter (annotations from this great bundle: JMSDiExtraBundle):

class BillingType extends \Symfony\Component\Form\AbstractType
{

    /**
     * @var array
     */
    private $billingChoices;

    /**
     * @InjectParams({"billingChoices" = @Inject("%billings%")})
     *
     * @param array $billingChoices
     */
    public function __construct(array $billingChoices)
    {
        $this->billingChoices = $billingChoices;
    }
} 

Answer

Leonov Mikhail picture Leonov Mikhail · Jun 7, 2012

You should add useAttributeAsKey('name') to your billing node configuration in Configurator.php.

More information about useAttributeAsKey() you can read at Symfony API Documentation

After changes billing node configuration it should be like:

->arrayNode('billings')
    ->isRequired()
    ->requiresAtLeastOneElement()
    ->useAttributeAsKey('name')
    ->prototype('scalar')->end()
->end()