Symfony2 TreeBuilderを使用したYAMLの再帰的構造
-
21-12-2019 - |
質問
symfonyの構成は、構成をvaldiatingに等しいです。
TreeBuilderで設定を検証したいです。 YML-exampleでは、Config-Treeがどのように見えるかの概要の例を示します(将来、ツリーは今よりも大きくなります)。しかし、これを行うには、構造を作成する必要があります。
今あなたは私を助けて、TreeBuilderを作成することができますか?私はArrayNodeとPrototypesですべてを試しましたが、うまくいきません。私は
"" "" "" "エラー:未定義のメソッドの呼び出しsymfony \ component \ config \定義\ builder \ NodeBuilder :: prototype()/ my/menubundle/dependencyinjection/configuration.php行29"
ベースアイデア:
symfony2-bundleを生成したい。これはHTMLで継代を作成します。 HTMLコードを生成するには、yaml-configurationをオブジェクト構造に引用する必要があります。これは機能しますが、symfonyの検証は機能しません...
MENU.YMLがどのように見えるかについての迅速な例です。
my_menu_structure:
menu:
name: test
cssClass: blubb
children:
child:
name: item1
route: route1
position: 0
child:
name: item11
route: route11
position: 0
child:
name: item2
route: route2
position: 1
.
今すぐSymfony2でTreeBuilderを設定したいが機能しません。
試したことの数回の後、これは私の最後のバージョンです:
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('my_menu');
$rootNode
->children()
->arrayNode('menu')
->scalarNode('cssClass')
->defaultValue(array())
->prototype('array')
->scalarNode('name')
->scalarNode('route')
->scalarNode('Position')
->prototype('array')
->end()
->end()
->end();
.
メニューとMenuItemのオブジェクトを構築しました。すべてがこれまでに動作しますが、TreeBuilderを設定することはできません。 私が探しているのは、TreeBuilderで部品(MenuItem-:Name、Route、子供)を再利用する方法ですが、私が今まで見つけたすべてのものは私を助けることができませんでした... 他のすべてが機能する、私の唯一の問題は、TreeBuilderを設定できず、$ this-> container-> get( 'menu.name')を使用してYMLから設定できません。これは例外をスローします。存在しないサービス "menu.name"を要求しました。
これまでのところ、Prototype( 'Array')で設定しましたが、PhpStormは毎回Prototypeまたは - > Prototype() - > children() - >→prototype() - > children() - > scalarnode()..
解決
Januari 2014からのこの質問は、ただし、エラーメッセージの解決策「未定義のメソッドSymfony \ Component \ Config \ Defination \ Builder \ ArrayNodeDefinition :: ArrayNode()」という名前の解決策を探しています。検索結果
受け入れられた答えは実際にはエラーメッセージの理由については言及していません。
元のポスターで与えられた例は次のとおりです。
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('my_menu');
$rootNode
->children()
->arrayNode('menu')
->scalarNode('cssClass')
->defaultValue(array())
->prototype('array')
->scalarNode('name')
->scalarNode('route')
->scalarNode('Position')
->prototype('array')
->end()
->end()
->end();
.
各ノードをend()
呼び出しで終了する必要があるため、これは正しくありません。
[文書] [1]の状態として:
一般:ノードを定義した後、end()への呼び出し()は階層内に1ステップアップします。
私自身の場合では、私には不明確でしたが、ArrayNode Despionでは、基になるarrayNode()
定義としてchildren()
定義を終了する必要があるという事実です。
そのため、上記の例は次のように正しいです。
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('my_menu');
$rootNode
->children()
->scalarNode('cssClass')->end()
->arrayNode('menu')
->prototype('array')
->scalarNode('name')->end()
->scalarNode('route')->end()
->scalarNode('Position')->end()
->end()
->end()
->end()
->end();
.
うまくいけば、これは他の人が私がしたよりも早く問題を解決するのに役立ちます。
他のヒント
what you can do is to configure your rootNode this way:
$rootNode
->children()
->arrayNode('menu')
->isRequired()
->prototype('array')
->children()
->scalarNode('label')->isRequired()->end()
->scalarNode('class')->end() // I added an optional class parameter
//others parameters
->arrayNode('sub_menu')
->prototype('array')
->children()
->scalarNode('label')->isRequired()->end()
->scalarNode('route')->end()
->scalarNode('class')->end()
// add as many parameters as you want for your children
->end()
->end()
->end()
->end()
->end()
->end();
Then you want to pass this variable to a service. Very simple class :
class AdminMenu
{
protected $menu;
public function setMenu($menu)
{
$this->menu = $menu;
}
public function getMenu()
{
return $this->menu;
}
}
In you services.xml
<parameter key="wf.admin_menu.class">Acme\AdminBundle\Library\AdminMenu</parameter>
<service id="wf.admin_menu" class="%wf.admin_menu.class%">
</service>
In your bundleAdminExtension class
$myServiceDefintion = $container->getDefinition('wf.admin_menu');
$myServiceDefintion->addMethodCall('setMenu', array($config['menu']));
Finally, in any controller you want:
$menu = $this->container->get('wf.admin_menu');
That's all :)
Edit : Here's what my config looks like
my_bundle_admin:
menu:
unique_key:
label : 'Level1-1'
class : ''
sub_menu:
sub_unique_key1:
label: 'Level2-1'
route: 'my_route'
sub_unique_key2:
label: 'Level2-2'
route: 'my_route'
unique_key_2:
label : 'Level1-2'
sub_menu :
sub_unique_key1:
label : 'Level2-1'
route : 'my_route'
sub_unique_key2:
label : 'Level2-2'
route : 'my_route'