2013-04-10 23 views
15

Nút cấu hình của tôi có thể source hỗ trợ cả hai giá trị stringarray?Làm cho nút cấu hình hỗ trợ cả chuỗi và mảng trong cấu hình Symfony 2?

Sourcing từ string:

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

Sourcing từ array:

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

Lớp mở rộng sẽ có thể phân biệt giữa chúng:

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

tôi có thể sử dụng một cái gì đó như thế này :

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

Nhưng làm thế nào tôi ca thêm những hạn chế về cấu trúc của source (hoạt động, lệnh, vv ...) đến nút biến (mà chỉ nên được áp dụng khi giá trị của nó là loại array)?

Trả lời

19

Tôi nghĩ bạn có thể sử dụng tính năng chuẩn hóa cấu hình bằng cách tái cấu trúc tiện ích của bạn.

Trong phần mở rộng của bạn thay đổi mã của bạn để kiểm tra xem một con đường được thiết lập

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

Và cho phép người dùng sử dụng một chuỗi cho config.

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

Như thế này bạn có thể cho phép người dùng sử dụng chuỗi hoặc mảng có thể xác thực.

Xem symfony documentation for normalisation

Hy vọng sẽ hữu ích. Trân trọng.

+0

Không tệ. Tôi nên xử lý các trường hợp khi 'đường dẫn' và' hoạt động' và 'lệnh' được giải quyết. +1 cho tôi – gremo

6

Có thể sử dụng một loại variable node kết hợp với một số logic xác nhận tùy chỉnh:

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

này sẽ thành công trình:

my_bundle: 
    source: foo 

# and 

my_bundle: 
    source: [foo, bar] 

nhưng nó sẽ không quá trình:

my_bundle: 
    source: 1 

# or 

my_bundle 
    source: ~ 

Tất nhiên, bạn sẽ không nhận được quy tắc xác thực hợp lệ cho cấu hình bình thường nút ation sẽ cung cấp cho bạn và bạn sẽ không thể sử dụng các quy tắc xác thực đó trên mảng (hoặc chuỗi) được truyền nhưng bạn sẽ có thể xác nhận hợp lệ dữ liệu được truyền trong bao đóng được sử dụng.

+0

Vâng, tôi đã sử dụng một cái gì đó như thế này. Nhưng lần này nút mảng rất phức tạp. – gremo

+0

Tôi không chắc chắn nếu nó có thể. Bạn không thể sử dụng cấu trúc khác như cấu trúc được sử dụng bởi JMSDiExtraBundle? –

Các vấn đề liên quan