2014-04-28 3 views
3

제공의 arrayNode를 생략 나는 내 Symfony2 프로젝트에 다음과 같은 구성이 있습니다Symfony2 구성 : 대신 빈 배열

<?php 

namespace Acme\CommonBundle\DependencyInjection; 

use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; 
use Symfony\Component\Config\Definition\Builder\NodeDefinition; 
use Symfony\Component\Config\Definition\Builder\TreeBuilder; 
use Symfony\Component\Config\Definition\ConfigurationInterface; 

/** 
* This is the class that validates and merges configuration from your app/config files 
* 
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class} 
*/ 
class Configuration implements ConfigurationInterface 
{ 
    /** 
    * {@inheritDoc} 
    */ 
    public function getConfigTreeBuilder() 
    { 
     $treeBuilder = new TreeBuilder(); 
     $rootNode = $treeBuilder->root('acme_common'); 

     $rootNode 
      ->children() 
       ->arrayNode('controller') 
        ->children() 
         ->arrayNode('controllers') // overwrite defaults declared above for specific controllers 
          ->prototype('array') 
           ->children() 
            ->scalarNode('title')->end() 
            ->append($this->addActionsNode()) 
            ->append($this->addViewsNode()) 
           ->end() 
          ->end() 
         ->end() 
        ->end() 
       ->end() 
      ->end(); 

     return $treeBuilder; 
    } 

    /** 
    * Add the actions node, e.g.: 
    * actions: 
    *  edit: 
    *   name: Edit 
    *   path: edit 
    *   icon: icon-edit 
    *   width: 45 
    *  archive: 
    *   name: Archive 
    *   path: archive 
    *   icon: icon-thrash 
    *   width: 75 
    * 
    * These are the actions that will be shown in the index view 
    * 
    * @return ArrayNodeDefinition|NodeDefinition 
    */ 
    protected function addActionsNode() 
    { 
     $node = $this->getNode('actions'); 

     $node 
      ->useAttributeAsKey('key') 
      ->prototype('array') 
       ->children() 
        ->scalarNode('name')->end() 
        ->scalarNode('path')->end() 
        ->scalarNode('icon')->end() 
        ->integerNode('width')->end() 
       ->end() 
      ->end(); 

     return $node; 
    } 

    /** 
    * Configure the templates used, e.g.: 
    * views: 
    *  index: :AcmeCommon:Crud/list.html.twig 
    *  edit: :AcmeCommon:Crud/edit.html.twig 
    * 
    * @return ArrayNodeDefinition|NodeDefinition 
    */ 
    protected function addViewsNode() 
    { 
     $node = $this->getNode('views'); 

     $node 
      ->children() 
       ->scalarNode('index')->end() 
       ->scalarNode('edit')->end() 
      ->end(); 

     return $node; 
    } 

    /** 
    * Helper function to build a node 
    * 
    * @param string $name 
    * 
    * @return \Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition|NodeDefinition 
    */ 
    protected function getNode($name) 
    { 
     $builder = new TreeBuilder(); 
     $node = $builder->root($name); 

     return $node; 
    } 
} 

아이디어는 내가 쓰고 있어요 CRUD 컨트롤러의 무리에 대한 몇 가지 물건을 구성 할 수입니다. 조치 및보기 노드는 선택적입니다. 특정 기본값을 덮어 쓰려는 경우에만 사용해야합니다. 당신이 actions이 선언되지 않은 경우, 여전히 빈 상태 (empty)의 배열로 추가되는 것을 볼 수 있듯이

Array 
(
    [controller] => Array 
     (
      [controllers] => Array 
       (
        [acme_foo_controller] => Array 
         (
          [title] => Foo 
          [actions] => Array 
           (
            [edit] => Array 
             (
              [name] => Edit 
              [path] => edit 
              [icon] => icon-edit 
              [width] => 45 
             ) 
           ) 
          [views] => Array 
           (
            [index] => :AcmeCommon:Foo/list.html.twig 
            [edit] => :AcmeCommon:Foo/edit.html.twig 
           ) 
         ) 
        [acme_bar_controller] => Array 
         (
          [title] => Bar 
          [views] => Array 
           (
            [index] => :AcmeCommon:Bar/list.html.twig 
           ) 
          [actions] => Array 
           (
           ) 
         ) 
        [acme_baz_controller] => Array 
         (
          [title] => Baz 
          [actions] => Array 
           (
           ) 
         ) 
       ) 
     ) 
) 

:이처럼 보이는 배열 결과

acme_common: 
    controller: 
     controllers: 
      acme_foo_controller: 
       title: Foo 
       actions: 
        edit: 
         name: Edit 
         path: edit 
         icon: icon-edit 
         width: 45 
       views: 
        index: :AcmeCommon:Foo/list.html.twig 
        edit: :AcmeCommon:Foo/edit.html.twig 
      acme_bar_controller: 
       title: Bar 
       views: 
        index: :AcmeCommon:Bar/list.html.twig 
      acme_baz_controller: 
       title: Baz 

: 같은 구성은 볼 수 있었다. 나는 단순히 생략 actions 있도록를 좋아하고 결과 배열이 같이있는 것 :

Array 
(
    [controller] => Array 
     (
      [controllers] => Array 
       (
        [acme_foo_controller] => Array 
         (
          [title] => Foo 
          [actions] => Array 
           (
            [edit] => Array 
             (
              [name] => Edit 
              [path] => edit 
              [icon] => icon-edit 
              [width] => 45 
             ) 
           ) 
          [views] => Array 
           (
            [index] => :AcmeCommon:Foo/list.html.twig 
            [edit] => :AcmeCommon:Foo/edit.html.twig 
           ) 
         ) 
        [acme_bar_controller] => Array 
         (
          [title] => Bar 
          [views] => Array 
           (
            [index] => :AcmeCommon:Bar/list.html.twig 
           ) 
         ) 
        [acme_baz_controller] => Array 
         (
          [title] => Baz 
         ) 
       ) 
     ) 
) 

이 가능합니까?

답변

1

xdebug를 사용하여 코드를 단계별로 처리했습니다. PrototypeNode에는 항상 빈 값 배열 인 기본값이있는 것으로 보입니다. 추가 프로빙은 완성 단계에서이 빈 배열이 적용되었음을 나타냅니다. 그러나이 단계의 마지막 단계는 최종 마무리 폐쇄를 적용하는 것입니다. 최종 종료는 정규화 종료 일 수도 있습니다. 원치 않는 빈 배열을 제거하려면 부모 노드에 normalize()->always()을 추가하고 수정 된 배열을 반환하는 클로저를 제공해야합니다.

귀하의 변형 예

:

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

    $rootNode 
     ->children() 
      ->arrayNode('controller') 
       ->children() 
        ->arrayNode('controllers') // overwrite defaults declared above for specific controllers 
         ->prototype('array') 
          ->validate() 
           ->always(function($v){ 
            if (empty($v['action'])) 
             unset($v['action']); 
            return $v; 
           }) 
          ->end() 
          ->children() 
           ->scalarNode('title')->end() 
           ->append($this->addActionsNode()) 
           ->append($this->addViewsNode()) 
          ->end() 
         ->end() 
        ->end() 
       ->end() 
      ->end() 
     ->end(); 

    return $treeBuilder; 
} 
+0

나는이 허용 대답해야한다고 생각합니다. @ 브람 당신이 동의합니까? – Sam