EC-CUBE3のプラグインのフックポイントについて
EC-CUBE Advent Calendar 2015 4日目の記事です。
4日目はEC-CUBE3でブラグインを実行する際に定義されているフックポイントについてです。
皆さんEC-CUBE3のプラグインを作っていますか?
プラグインの開発に慣れていくに従って段々と疑問に思ってくるのがフックポイントについてです。
勉強会などを行うときに必ず聞かれる内容として 「各フックポイントの実行タイミングが良く分からない」と尋ねられます。
今回は簡単に各フックポイントについてまとめました。
フックポイントを説明する前に先ずはSymfony2では標準で
- kernel.request
- kernel.controller
- kernel.view
- kernel.response
- kernel.exception
というイベントが存在しています。
詳しくはこちら。 The HttpKernel Component (The Symfony Components)
EC-CUBE3ではSymfony2のイベント
- kernel.request
- kernel.response
- kernel.terminate
の各イベントに対して処理を挟み込めるフックポイントが用意されています。
詳しくはこちら。ミドルウェア (Middlewares) | Japan Symfony Group
EC-CUBE3で用意されているフックポイントについて *1
Middleware
- アプリケーション全体の処理の前後・特定のページの処理の前後に 処理を介入させることができます。
- 全てのControllerに対して介入が可能です。
FilterResponseEvent
- Responseが返却される描画される直前のHTTP HeaderやBodyを 書き換えることができます。
- HTMLだけでなく、JSONで返却したいなどの変更も可能です。
今までの説明だけではさっぱり分からないと思いますので、実際に動作をさせてみましょう。
今回はプラグインの作成方法について説明は割愛しますが、 こういうプラグインを作って用意されているフックポイントの実行タイミングを確認してみました。
- config.yml
name: フックポイント確認プラグイン code: HookPoint version: 1.0.0 event: HookPointEvent
- event.yml
eccube.event.app.before: - [onAppBefore, NORMAL] eccube.event.app.after: - [onAppAfter, NORMAL] eccube.event.controller.homepage.before: - [onControllerBefore, NORMAL] eccube.event.controller.homepage.after: - [onControllerAfter, NORMAL] eccube.event.controller.homepage.finish: - [onControllerFinish, NORMAL] eccube.event.render.homepage.before: - [onRenderBefore, NORMAL]
- HookPointEvent.php
<?php
namespace Plugin\HookPoint;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
class HookPointEvent
{
/** @var \Eccube\Application $app */
private $app;
public function __construct($app)
{
$this->app = $app;
}
public function onAppBefore()
{
error_log("onAppBefore");
}
public function onAppAfter()
{
error_log("onAppAfter");
}
public function onControllerBefore()
{
error_log("onControllerBefore");
}
public function onControllerAfter()
{
error_log("onControllerAfter");
}
public function onControllerFinish()
{
error_log("onControllerFinish");
}
public function onRenderBefore(FilterResponseEvent $event)
{
error_log("onRenderBefore");
}
}
- TopController.php
use Eccube\Application;
class TopController
{
public function index(Application $app)
{
error_log('TopController::index')
return $app->render('index.twig');
}
}
- ApplicationTrait.php(一部抜粋)
public function render($view, array $parameters = array(), Response $response = null)
{
$twig = $this['twig'];
if ($response instanceof StreamedResponse) {
$response->setCallback(function () use ($twig, $view, $parameters) {
$twig->display($view, $parameters);
});
} else {
if (null === $response) {
$response = new Response();
}
$response->setContent($twig->render($view, $parameters));
}
error_log("twig render");
return $response;
}
これらを実行すると以下が出力されます。(実際にはもう少し出力されますが)
onAppBefore onControllerBefore TopController::index twig render onControllerAfter onRenderBefore onAppAfter onControllerFinish
最初に実行されるのが
eccube.event.app.before
であとは大体想定通りと思いますが、意外だったのが
onControllerFinish
です。onAppAfterより後に実行されるのは想定外でしたが、この順番で実行されていきます。
では、それぞれのフックポイントのイベントについては何を記述すれば良いかというと、
| フックポイント | 処理の内容など | Symfony2に対応するイベント |
|---|---|---|
| onAppBefore | アプリケーション共通の前処理を記述 | kernel.request (EARLY_EVENT) |
| onAppAfter | アプリケーション共通の後処理を記述 | kernel.request (LATE_EVENT) |
| onControllerBefore | Controllerが実行される前に行う処理を記述 | kernel.request |
| onControllerAfter | Controllerが実行された後に行う処理を記述 | kernel.response |
| onControllerFinish | Controllerが最後まで実行された後に行う処理を記述 | kernel.terminate |
| onRenderBefore | Viewに対して項目の追加などを行う処理を記述 | kernel.response |
になります。
プラグインを作成していて画面の拡張や処理の拡張をする場合、どのイベントに対して記述すれば分からないときはこちらの表を参考にしてください。
この記事がフックポイントについての理解について手助けになれば幸いです。
EC-CUBEプラグインアワードの締め切りも近いので是非ご応募お待ちしております。 www.ec-cube.net
5日目は@tuyop1です。