1

プラグインと完全に互換性のあるアプリケーションを作成する最善の方法を考えています。

アクションとフィルターを定義してプラグインで使用できるWordpressプラグインの概念に慣れています。そのため、他のユーザーは、アクション (またはフィルター) が呼び出されたときに実行されるプラグインのメソッドを定義できます。

私の考えは、いくつかのアクションとフィルターを使用してアプリを作成し、その後、他の開発者が「通常の」アプリ フローに干渉するバンドルを作成できるようにすることです...

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 の優先順位を使用して、メニューの項目の各グループの位置を設定できます。

4

1 に答える 1

0

他の開発者がカスタム動作をフックできるアプリケーションの拡張ポイントを提供するための良い出発点は、SymfonyのEventDispatcherコンポーネント ( Observer パターンの実装) を使用することです。

Symfony はすでに独自のコア ( HttpKernel ) でこのコンポーネントを広範囲に使用して、他のコンポーネント (または必要に応じてプラグイン) が http リクエスト -> レスポンス フローのさまざまなポイントにフックし、リクエスト マッチングからレスポンス生成まですべてを処理できるようにします。

たとえば、イベントにフックしてkernel.request、リクエストが有効でない場合にすぐにレスポンスを返したり、イベントにフックしkernel.responseてレスポンスの内容を変更したりできます。

デフォルトの KernelEventsの完全なリストを参照してください。

これらのみを使用することで (他のコンポーネントに関連するものは他にもたくさんあります)、Wordpress の「プラットフォーム」よりも機能が高く、テストしやすく、堅牢なプラグイン システムを作成できます。

もちろん、ブログ アプリケーションのビジネス ロジックに適した独自のイベントを簡単に作成してディスパッチできます (たとえば、post.createdやのようなイベントを作成します)。comment.created

ここで、例として、生成された応答で何かを実行し、別のイベント (別のプラグインで使用できる) を発生させる「プラグイン」を構成する方法を次に示します。

namespace Vendor;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;

class ResponseAlter implements EventSubscriberInterface
{

    private $dispatcher;

    public function __construct(EventDispatcher $dispatcher)
    {
        $this->dispatcher = $dispatcher;
    }

    public function doSomethingWithResponse(FilterResponseEvent $event)
    {
        $response = $event->getResponse();

        /**
         * let other plugins hook to the provide.footer event and
         * add the result to the response
         */
        $footer = new ProvideFooterEvent();
        $this->dispatcher->dispatch('provide.footer', $footer);

        $this->addFooterProvidedByPluginToResponse($response, $footer->getProvidedFooter());

        $event->setResponse($response);
    }

    static function getSubscribedEvents() 
    {
        return array(
            'kernel.response' => 'doSomethingWithResponse'
        );
    }
}

これで、サービスをサービス サブスクライバーとしてタグ付けするだけで完了です。HttpKernelコンポーネントをプラグインしました。

services:
    my_subscriber:
        class: Vendor\ResponseAlter
        arguments: ['@event_dispatcher']
        tags:
            - {name: kernel.event_subscriber}
于 2013-01-31T21:58:54.117 に答える