Symfony 4.3 + ApiPlatform +接受语言

时间:2019-07-10 12:31:48

标签: php symfony api-platform.com

我刚开始使用Api平台,但是在翻译验证程序的消息时遇到问题。

我已经

...创建了两个带有翻译的文件:/translations/validators.en.yaml和/translations/validators.fr.yaml

...添加了适当的自定义验证器消息

...将default_locale设置为 en

...在实体中添加了翻译验证器定义:

/**
 * @ORM\Column(type="text", nullable=true)
 * @Assert\NotBlank(message="test.message")
 */
private $title;

此后,我的自定义翻译消息将正确返回。

现在,我想启用依赖于Accept-Language标头而不是default_locale的翻译。

我知道symfony不会在Accept-Language标头上中继。取而代之的是,我创建了负责确定首选语言的订户(通过Accept-Language):


namespace App\EventSubscriber;

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

class LocaleSubscriber implements EventSubscriberInterface
{
    public function onKernelRequest(GetResponseEvent $event)
    {
        $request = $event->getRequest();
        $locale = substr($request->getPreferredLanguage(), 0, 2);

        $request->setDefaultLocale($locale);
        $request->setLocale($locale);
    }

    public static function getSubscribedEvents()
    {
        return [
           'kernel.request' => 'onKernelRequest',
        ];
    }
}

不幸的是,这种方式行不通。即使我直接将'fr'作为参数作为setLocale和setDefaultLocale的参数,翻译仍然在kernel.default_locale上进行。

有人知道如何解决我的问题吗?

2 个答案:

答案 0 :(得分:0)

看看此Symfony文档页面: https://symfony.com/doc/current/session/locale_sticky_session.html

我认为您的侦听器应具有更高的优先级(例如20),因此应在本地侦听器之前加载。

答案 1 :(得分:0)

我同意前面的答案,但是还有另一个问题:浏览器在区域设置中使用破折号,而Symfony使用下划线。这是一个完整的解决方案:

// https://github.com/metaclass-nl/tutorial-api-platform/blob/chapter4-api/api/src/EventSubscriber/LocaleSubscriber.php

namespace App\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\HeaderUtils;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class LocaleSubscriber implements EventSubscriberInterface
{

    public function onKernelRequest(RequestEvent $event)
    {
        $request = $event->getRequest();
        $accept_language = $request->headers->get("accept-language");
        if (empty($accept_language)) {
            return;
        }
        $arr = HeaderUtils::split($accept_language, ',;');
        if (empty($arr[0][0])) {
            return;
        }

        // Symfony expects underscore instead of dash in locale
        $locale = str_replace('-', '_', $arr[0][0]);

        $request->setLocale($locale);
    }

    public static function getSubscribedEvents()
    {
        return [
            // must be registered before (i.e. with a higher priority than) the default Locale listener
            KernelEvents::REQUEST => [['onKernelRequest', 20]],
        ];
    }
}