2013-04-10 3 views
15

Kann mein Konfigurationsknoten source sowohl string als auch Werte unterstützen?Konfigurationsknoten unterstützen sowohl String als auch Array in Symfony 2-Konfiguration?

Beschaffung von string:

# Valid configuration 1 
my_bundle: 
    source: %kernel.root_dir%/../Resources/config/source.json 

Beschaffung von array:

# Valid configuration 2 
my_bundle: 
    source: 
     operations: [] 
     commands: [] 

Die Erweiterung Klasse wäre in der Lage sein, zwischen ihnen zu unterscheiden:

if (is_array($config['source']) { 
    // Bootstrap from array 
} else { 
    // Bootstrap from file 
} 

ich so etwas wie diese verwenden könnte :

$rootNode->children() 
    ->variableNode('source') 
     ->validate() 
      ->ifTrue(function ($v) { return !is_string($v) && !is_array($v); }) 
      ->thenInvalid('Configuration value must be either string or array.') 
     ->end() 
    ->end() 
->end(); 

Aber wie ca ich hinzufügen, Einschränkungen für die Struktur von source (Operationen, Befehlen, etc ...) auf den variablen Knoten (das nur durchgesetzt werden soll, wenn sein Wert vom Typ array)?

Antwort

19

Ich denke, dass Sie die Config-Normalisierung verwenden können, indem Sie Ihre Erweiterung refactoring.

In Ihrer Erweiterung Code ändern, wenn ein Pfad

gesetzt
if ($config['path'] !== null) { 
    // Bootstrap from file. 
} else { 
    // Bootstrap from array. 
} 

und ermöglicht es dem Benutzer zu überprüfen, eine Zeichenfolge für Konfiguration verwendet werden.

So können Sie dem Benutzer erlauben, eine Zeichenfolge oder ein Array zu verwenden, das validiert werden kann.

Siehe symfony documentation for normalisation

Hoffe, dass es hilfreich ist. Beste Bewertung.

+0

Nicht schlecht. Ich sollte den Fall behandeln, wenn 'path' und' operations' und 'commands' gesetzt sind. +1 für mich – gremo

6

Es ist möglich, eine variable node Art in Kombination mit einiger benutzerdefinierten Validierungslogik zu verwenden:

<?php 
use Symfony\Component\Config\Definition\Builder\TreeBuilder; 
use Symfony\Component\Config\Definition\Exception\InvalidTypeException; 

public function getConfigTreeBuilder() 
{ 
    $treeBuilder = new TreeBuilder(); 
    $rootNode = $treeBuilder->root('my_bundle'); 

    $rootNode 
     ->children() 
      ->variableNode('source') 
       ->validate() 
        ->ifTrue(function ($v) { 
         return false === is_string($v) && false === is_array($v); 
        }) 
        ->thenInvalid('Here you message about why it is invalid') 
       ->end() 
      ->end() 
     ->end(); 
    ; 

    return $treeBuilder; 
} 

Dies wird erfolgreich Prozess:

my_bundle: 
    source: foo 

# and 

my_bundle: 
    source: [foo, bar] 

aber es wird nicht Prozess:

my_bundle: 
    source: 1 

# or 

my_bundle 
    source: ~ 

Natürlich werden Sie nicht die netten Validierungsregeln eine normale Konfiguration erhalten Dieser Knoten wird Ihnen zur Verfügung stehen, und Sie können diese Validierungsregeln nicht für das übergebene Array (oder die Zeichenfolge) verwenden, aber Sie können die übergebenen Daten im verwendeten Closure validieren.

+0

Ja, ich habe schon so etwas benutzt. Aber diesmal ist der Array-Knoten sehr komplex. – gremo

+0

Ich bin mir nicht sicher, ob es möglich ist. Können Sie keine andere Struktur wie die von JMSDiExtraBundle verwenden? –

Verwandte Themen