0

リクエストごとに呼び出さなければならない関数をSymfony2に追加する必要があります。(リクエストとセッションでの言語検出)

Controllerクラスのコンストラクターでこれを行うことを考えましたが、コンテナーが不明/作成されていません。

これについての提案はありますか?

4

4 に答える 4

3

イベントリスナーを定義できます

イベントリスナーの作成に関するドキュメントをお読みください。

于 2012-10-28T15:58:58.353 に答える
1

これは、ユーザー構成で設定された言語でページにリダイレクトするリスナーです。ニーズに合わせて調整してください。

<?php
namespace MyVendor\Listener;

use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Routing\RouterInterface;
use JMS\DiExtraBundle\Annotation\Service;
use JMS\DiExtraBundle\Annotation\InjectParams;
use JMS\DiExtraBundle\Annotation\Observe;

/**
 * @Service
 */
class LanguageListener
{
    /**
     * @var \Symfony\Component\Security\Core\SecurityContextInterface
     */
    private $securityContext;

    /**
     * @var \Symfony\Component\Routing\RouterInterface
     */
    private $router;

    /**
     * @InjectParams
     *
     * @param \Symfony\Component\Security\Core\SecurityContextInterface $securityContext
     * @param \Symfony\Component\Routing\RouterInterface $router
     */
    public function __construct(
        SecurityContextInterface $securityContext, 
        RouterInterface $router
    ) {
        $this->securityContext = $securityContext;
        $this->router          = $router;
    }

    /**
     * @Observe("kernel.request")
     *
     * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
     */
    public function forceLanguage(GetResponseEvent $event)
    {
        if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
            return;
        }

        $token = $this->securityContext->getToken();

        if (!$token) {
            return;
        }

        if (!$this->securityContext->isGranted('ROLE_USER')) {
            return;
        }

        /** @var $request \Symfony\Component\HttpFoundation\Request */
        $request = $event->getRequest();
        $locale  = $request->getLocale();
        $route   = $request->get('_route');

        if ('_' === $route[0]) {
            return;
        }

        /** @var $user \MyVendor\Model\User */
        $user = $token->getUser();

        if ($user->getConfig()->getLanguage() !== $locale) {
            $parameters = array_merge($request->attributes->get('_route_params'), [
                '_locale' => $user->getConfig()->getLanguage(),
            ]);

            $path = $this->router->generate($route, $parameters);
            $event->setResponse(new RedirectResponse($path));
        }
    }
}
于 2012-10-29T10:22:07.723 に答える
0

それはあなたが何をしようとしているのかによると思います。言語検出の場合、ほとんどの場合、symfonyとそのバンドルは事実上すべてを処理します。つまり、ルーティングをカスタマイズする場合は、routing.loaderタグを使用してルーティングコンポーネントを拡張する必要があります。ただし、イベントリスナーを使用できる場合でも、そこから変更できるものの数がわかりません。

于 2012-10-28T16:02:47.273 に答える
0

上記のようにイベントを使用するか、何か簡単なものが必要な場合は使用してください。

メソッドをオーバーライドできますsetContainer

namespace My\Namespace;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface;

class MyController extends Controller 
{
    private $foo;

    public function setContainer(ContainerInterface $container = null)
    {
        parent::setContainer($container);
        $this->foo = 'bar';
    }
    // your actions
}
于 2012-10-29T09:58:51.073 に答える