2013-03-27 16 views
0

我正在製作一個管理菜單捆綁包。我希望其他捆綁包能夠將菜單項添加到捆綁包中,但我還希望刪除捆綁包時刪除菜單項。什麼是最好的方法來做到這一點?如何在Symfony2中進行捆綁通信

我可以創建一個「重新生成管理菜單」操作,掃描所有的YML包,然後將其存儲在緩存或數據庫中。

有沒有更好的方式來做到這一點?

回答

3

您可以使用tags從其他包(甚至相同)中查找服務,並使用它們從compiler pass中構建菜單。

在這個例子中,我將假設你將你的菜單定義爲服務(我將使用服務ID acme_menu.menu)。

// src/Acme/MenuBundle/DependencyInjection/Compiler/BuildMenuCompilerPass.php 
namespace Acme\MenuBundle\DependencyInjection\Compiler; 

use Symfony\Component\DependencyInjection\ContainerBuilder; 
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 
use Symfony\Component\DependencyInjection\Reference; 

class BuildMenuCompilerPass implements CompilerPassInterface 
{ 
    public function process(ContainerBuilder $container) 
    { 
     if (!$container->hasDefinition('acme_menu.menu')) { 
      return; 
     } 

     $definition = $container->getDefinition('acme_menu.menu'); 

     $taggedServices = $container->findTaggedServiceIds('acme_menu.item'); 
     foreach ($taggedServices as $id => $attributes) { 
      $definition->addMethodCall(
       'addMenuItem', 
       array(new Reference($id)) 
      ); 
     } 
    } 
} 

與你的菜單包註冊它:

// src/Acme/MenuBundle/AcmeMenuBundle.php 
namespace Acme\MenuBundle; 

use Symfony\Component\HttpKernel\Bundle\Bundle; 
use Symfony\Component\DependencyInjection\ContainerBuilder; 

use Acme\MenuBundle\DependencyInjection\Compiler\BuildMenuCompilerPass; 

class AcmeMenuBundle extends Bundle 
{ 
    public function build(ContainerBuilder $container) 
    { 
     parent::build($container); 

     $container->addCompilerPass(new BuildMenuCompilerPass()); 
    } 
} 

而且每個服務標記爲acme_menu.item將被添加到菜單 - 他們的方法addMenuItem將在菜單上調用它的創作與標記業務作爲參數。所以簡單定義:

# services.yml 
services: 
    acme_demo.menu.item1: 
     # ... 
     tags: 
      - { name: acme_menu.item } 
    acme_demo.menu.item2: 
     # ... 
     tags: 
      - { name: acme_menu.item }