2012-06-07 5 views
20

Fondamentalmente Vorrei consentire un arbitrario (ma non vuoto) Numero di coppie di valori-chiave nella mia configurazione, sotto billings nodo, cioè definire un array associativo.Consentire coppie di valori-chiave in configurazione semantica Symfony 2 Fascio

ho questo nel mio Configurator.php (parte di):

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

E poi, a mio config.yml:

my_bundle: 
    billings: 
     monthly : Monthly 
     bimonthly : Bimonthly 

Tuttavia, l'output $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(); 
    } 

} 

. .. quello che ottengo è indice di serie per numero, non un associativa uno:

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

Per curiosità (e se questo può aiutare), sto cercando di iniettare questo array come parametro di servizio (le annotazioni di questo gran fascio: 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; 
    } 
} 

risposta

21

È necessario aggiungere useAttributeAsKey('name') alla configurazione del nodo di fatturazione in Configurator.php.

Maggiori informazioni su useAttributeAsKey() potete leggere a Symfony API Documentation

Dopo la configurazione del nodo cambia fatturazione dovrebbe essere come:

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

Grazie, sto dando una prova e riferire! – gremo

+0

Cosa fare se si desidera evitare 'isRequired' e fornire una matrice predefinita in caso di null? –

+1

Sto correggendo che in '-> useAttributeAsKey ('name')' il 'name' ha un significato speciale o è almeno automaticamente aggiunto all'array? – martin

1

Recentemente ho avuto per impostare alcune configurazioni array nidificato.

esigenze sono state

  • Un primo array livello con pulsanti personalizzati (discribing un percorso entità)
  • Ciascuno di tali matrici doveva avere uno o più arbitrari tag come chiavi, con valore booleano.

Per ottenere tale configurazione, è necessario eseguire il metodo prototype().

Così, la seguente configurazione:

my_bundle: 
    some_scalar: my_scalar_value 
    first_level: 
     "AppBundle:User": 
      first_tag: false 
     "AppBundle:Admin": 
      second_tag: true 
      third_tag: false 

possono essere ottenuti utilizzando la seguente configurazione:

$treeBuilder = new TreeBuilder(); 
$rootNode = $treeBuilder->root('my_bundle'); 
$rootNode 
    ->addDefaultsIfNotSet() # may or may not apply to your needs 
    ->performNoDeepMerging() # may or may not apply to your needs 
    ->children() 
     ->scalarNode('some_scalar') 
      ->info("Some useful tips ..") 
      ->defaultValue('default') 
      ->end() 
     ->arrayNode('first_level') 
      ->info('Useful tips here..') 
      # first_level expects its children to be arrays 
      # with arbitrary key names 
      ->prototype('array') 
       # Those arrays are expected to hold one or more boolean entr(y|ies) 
       # with arbitrary key names 
       ->prototype('boolean') 
        ->defaultFalse()->end() 
       ->end() 
      ->end() 
     ->end() 
    ->end(); 
return $treeBuilder; 

Dumping $ config dall'interno della classe di estensione ha pronunciato la seguente uscita:

Array 
(
    [some_scalar] => my_scalar_value 
    [first_level] => Array 
     (
      [AppBundle:User] => Array 
       (
        [first_tag] => 
       ) 

      [AppBundle:Admin] => Array 
       (
        [second_tag] => 1 
        [third_tag] => 
       ) 
     ) 
) 

E voilà!

0

Questo è ciò che realmente fa useAttributeAsKey:

/** 
* Sets the attribute which value is to be used as key. 
* 
* This is useful when you have an indexed array that should be an 
* associative array. You can select an item from within the array 
* to be the key of the particular item. For example, if "id" is the 
* "key", then: 
* 
*  array(
*   array('id' => 'my_name', 'foo' => 'bar'), 
* ); 
* 
* becomes 
* 
*  array(
*   'my_name' => array('foo' => 'bar'), 
* ); 
* 
* If you'd like "'id' => 'my_name'" to still be present in the resulting 
* array, then you can set the second argument of this method to false. 
* 
* This method is applicable to prototype nodes only. 
* 
* @param string $name   The name of the key 
* @param bool $removeKeyItem Whether or not the key item should be removed 
* 
* @return ArrayNodeDefinition 
*/ 
public function useAttributeAsKey($name, $removeKeyItem = true) 
{ 
    $this->key = $name; 
    $this->removeKeyItem = $removeKeyItem; 

    return $this; 
}