2013-11-03 54 views
0

我試圖創建一個包來管理一個可以通過配置文件進行配置的菜單。配置樹:添加條件驗證

所以我寫了一些配置約束在我的class DependencyInjection\Configuration

需要的配置是必須添加到菜單中的一組項目。每個項目可以有3種不同的類型(link,link_notification,widget)。對於每種類型,物品都需要其他屬性(如route,label等)。配置的

實施例:

menu: 
    utilities: 
     - { type: link, icon: icon_name, label: text, route: { name: route_name, params: {} } } 
     - { type: link_notification, notification: notification_text } 
     - { type: widget, controller: controller_name } 

我卡因爲我無法找到如何定義爲每種類型的不同陣列的約束。

我無法找到一個方法來轉換條件:

IF type == "link" THEN scalarNode "icon" IS REQUIRED AND scalarNode "label" IS REQUIRED ... 

配置文件是這樣的:

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

     $rootNode 
      ->children() 
       ->arrayNode('utilities') 
        ->prototype('array') 
         ->children() 
          ->enumNode('type') 
           ->values(array ('link', 'link_notification', 'widget')) 
           ->isRequired() 
          ->end() 
         ->end() 
        ->end() 
       ->end() 
      ->end(); 

     return $treeBuilder; 
    } 

我見過的Symfony2文檔的方法->ifXXX() [...] ->then(),但我想不通了解如何在這種情況下使用它們。

回答

1

這將是這樣的:(沒有測試,但它給你一些方向尋找)

$rootNode 
    ->children() 
     ->arrayNode('utilities') 
      ->prototype('array') 
       ->validation() 
        ->ifTrue(function ($v) { 
         if (!is_array($v)) { 
          return true; 
         } 

         switch ($v['type']) { 
          case 'link': 
           $requiredSettings = array('icon', 'label', 'route'); 
           break; 

          case 'link_notification': 
           $requiredSettings = array('notification'); 
           break; 

          case 'widget': 
           $requiredSettings = array('controller'); 
           break; 
         } 

         foreach ($requiredSettings as $setting) { 
          if (!array_key_exists($setting, $v)) { 
           return false; 
          } 
         } 

         return true; 
        }) 
        ->thenInvalid('Missing required options for "%s"') 
       ->end() 
       ->children() 
        ->enumNode('type') 
         ->values(array ('link', 'link_notification', 'widget')) 
         ->isRequired() 
        ->end() 
       ->end() 
      ->end() 
     ->end() 
    ->end();