2013-04-10 9 views
15

設定ノードsourceは、stringarrayの両方の値をサポートできますか?設定ノードでSymfony 2設定の文字列と配列の両方をサポートしていますか?

stringからソーシング:arrayから

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

がソーシング:

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

拡張クラスは、それらを区別することができるでしょう:

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

私はこのようなものを使用する場合があります:

$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(); 

しかし、どのように私は(その値がタイプarrayであるときにのみ実施されなければならない)変数ノードにsource(操作、コマンド、等...)の構造上の制約を追加CA?

答えて

19

あなたの拡張機能をリファクタリングすることで、設定の正規化を使用できると思います。あなたの拡張機能で

はパスが

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

を設定されているかどうかを確認するようにコードを変更し、ユーザーが設定のための文字列を使用することができます。

$rootNode 
    ->children() 
     ->arrayNode('source') 
      ->beforeNormalization() 
      ->ifString() 
       ->then(function($value) { return array('path' => $value); }) 
      ->end() 
      ->children() 
       ->scalarNode('foo') 
       // ... 
      ->end() 
     ->end() 
    ->end() 
; 

このように、ユーザーは検証可能な文字列または配列を使用できます。

symfony documentation for normalisation

は、それが参考に願っています参照してください。

+0

悪くない。私は、 'path'と' operations'と 'commands'が設定されている場合に対処する必要があります。 +1 – gremo

6

いくつかのカスタム検証ロジックとの組み合わせでvariable nodeタイプを使用することが可能である:

<?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; 
} 

これは、プロセスを正常にします:

my_bundle: 
    source: foo 

# and 

my_bundle: 
    source: [foo, bar] 

が、それは処理されません:

my_bundle: 
    source: 1 

# or 

my_bundle 
    source: ~ 

もちろん、正常な検証ルールは通常のコンフィグレーションにはなりませんationノードが提供し、渡された配列(または文字列)に対してこれらの検証規則を使用することはできませんが、渡されたデータを使用されたクロージャで検証できます。

+0

はい、既にこのようなものを使用しています。しかし、今回はアレイノードが非常に複雑です。 – gremo

+0

可能かどうかわかりません。 JMSDiExtraBundleで使用されているような別の構造体を使用できませんか? –

関連する問題