今回はtwigで参照する変数を、なんとかグローバル変数にできないか?というお話です。
twigで値を参照したい場合、通常であればControllerで値を取得し、returnしてtwigに渡すようにカスタマイズするのが一般的かと思います。
でも、sessionやcookieに保持している値を全twigで表示しようと思うと、全画面のControllerとtwigのカスタマイズを行わなければなりません。
それは、非常にコストがかかる!
もっと簡単な方法はないものでしょうか。。。?
例えば、Customerがログインを行なった場合、認証が通った後で会員の今までに購入した金額によって
- 今までの購入金額が1000円未満の場合は、Aグループに所属するCustomer
- 今までの購入金額が3万円未満の場合は、Bグループに所属するCustomer
- 上記以外の場合は、Cグループに所属するCustomer
上記の範囲で会員のグループ分けします。
会員が所属しているクループによって、文言の出しわけをしてください。
こんな依頼は結構あるもので。。。
Controllerでセッション情報を取得して、文言を変数に入れてtwigにreturn。。。
そんなことはしなくても大丈夫です。
皆様はEventSubscriberをご存知ですか?
今回は、EventSubscriberの力を借りて、twigで参照できるグローバル変数を作成してみましょう。
app/Customize/EventListener配下にTwigInitializeListener.phpを作成しましょう。
TwigInitializeListener.phpの中身は、下記のようになります。
<?php
namespace Customize\EventListener;
use Eccube\Request\Context;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment;
class TwigInitializeListener implements EventSubscriberInterface
{
/**
* @var bool 初期化済かどうか.
*/
protected $initialized = false;
/**
* @var Environment
*/
protected $twig;
/**
* @var Context
*/
protected $requestContext;
/**
* TwigInitializeListener constructor.
*
* @param Environment $twig
* @param Context $context
*/
public function __construct(
Environment $twig,
Context $context
) {
$this->twig = $twig;
$this->requestContext = $context;
}
public function onKernelRequest(GetResponseEvent $event)
{
if ($this->initialized) {
return;
}
if ($this->requestContext->isFront()) {
$customerGroup = $event->getRequest()->get('customer_group');
$this->twig->addGlobal('customerGroup', $customerGroup);
}
$this->initialized = true;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
KernelEvents::REQUEST => [
['onKernelRequest', 20],
],
];
}
}
処理が記載できたら、あとはtwigの修正をするだけです。
{% if customerGroup == 'A' %}
<div>
<p>今月末までに1000円以上購入されると、プチクーポンをプレゼント</p>
</div>
{% elseif customerGroup == 'B' %}
<div>
<p>今月末までに3万円以上購入されると、豪華クーポンをプレゼント</p>
</div>
{% else %}
<div>
<p>クーポン取得済みです。</p>
</div>
{% endif %}
TwigInitializeListener.phpを作成することで、twig側でcustomerGroupという変数をControllerを経由せずに使うことができるようになっていると思います。
Controllerの経由が不要なので、静的ページからでも参照できます。
コストを掛けずにカスタマイズできる方法があるのは、良いことですね。