我想知道创建与插件完全兼容的应用程序的最佳方法。
我习惯了 Wordpress 插件概念,您可以定义操作和过滤器,然后在您的插件中使用。所以其他人可以在他们的插件上定义在调用动作(或过滤器)时执行的方法。
我的想法是使用一些操作和过滤器创建我的应用程序,然后其他开发人员可以构建一个干扰“正常”应用程序流程的 Bundle...
我正在阅读有关 Symfony2 依赖注入的信息,但我没有找到一些全面的示例来执行我想要的类似操作。
- 有人有一个我正在寻找的类似东西的真实例子吗?
- 依赖注入是最好的解决方案还是我应该构建自己的插件处理程序?
编辑:
我做了什么来允许其他包将项目添加到我的 knp-menu 菜单中。
在我的基础包中:
定义允许订阅者获取和设置菜单数据的过滤器:
# BaseBundle/Event/FilterMenuEvent.php
class FilterMenuEvent extends Event
{
protected $menu;
public function __construct($menu)
{
$this->menu = $menu;
}
public function getMenu()
{
return $this->menu;
}
}
定义菜单事件:
# Event/MenuEvents.php
final class MenuEvents
{
const BEFORE_ITEMS = 'menu.before.items';
const AFTER_ITEMS = 'menu.after.items';
}
设置订阅者:
# Event/MenuSubscriber.php
class MenuSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
'menu.after.items' => array(
array('homeItems', 9000),
array('quickactionsItems', 80),
array('adminItems', 70),
...
array('logoutItems', -9000),
)
);
}
public function homeItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Home', array('route' => 'zashost_zaspanel_homepage'));
}
public function quickactionsItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Quick actions', array( 'route' => null));
$menu['Quick actions']->addChild('Add hosting', array( 'route' => 'zashost_zaspanel_register_host'));
}
}
菜单生成中的调度事件:
# Menu\Builder.php
class Builder extends ContainerAware
{
public function userMenu(FactoryInterface $factory, array $options)
{
$menu = $factory->createItem('root');
$this->container->get('event_dispatcher')->dispatch(MenuEvents::AFTER_ITEMS , new FilterMenuEvent($menu));
return $menu;
}
}
将订阅者附加到内核事件订阅者:
# services.yml
services:
# Menu items added with event listener
base_menu_subscriber:
class: Acme\BaseBundle\Event\MenuSubscriber
arguments: ['@event_dispatcher']
tags:
- {name: kernel.event_subscriber}
然后在第三方捆绑包中:
设置我的第三方事件订阅者:
class MenuSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
'menu.after.items' => array('afterItems', 55)
);
}
public function afterItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Backups', array( 'route' => null));
$menu['Backups']->addChild('Create new backup', array( 'route' => null));
return $menu;
}
}
并附加到内核事件订阅者:
# srevices.yml
services:
menu_subscriber:
class: Acme\ThirdPartyBundle\Event\MenuSubscriber
arguments: ['@event_dispatcher']
tags:
- {name: kernel.event_subscriber}
这样我就可以使用 Event Dispatcher 的优先级来设置菜单中每组项目的位置。