相对于Symfony2中的Locale参数的约束

时间:2013-08-22 14:27:37

标签: php symfony

我需要针对坏词词典(例如数组)验证表单字段。所以要做到这一点,我必须创建一个新的Constraint + ConstraintValidator。它工作得很好,我唯一的问题是我想为不同的语言环境设置不同的词典。

示例:

namespace MyNameSpace\Category\MyFormBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class ContainsNoBadWordsValidator extends ConstraintValidator
{
    protected $badWordsEN = array('blabla');
    protected $badWordsFR = array('otherblabla');

    public function validate($value, Constraint $constraint)
    {
        if (in_array(strtolower($value), array_map('strtolower', $this->getBadWords()))) {
            $this->context->addViolation($constraint->message, array('{{ value }}' => $value));
        }
    }

    protected function getBadWords($locale = 'EN')
    {
        switch ($locale) {
            case 'FR':
                return $this->badWordsFR;
                break;
            default:
                return $this->badWordsEN;
                break;
        }
    }

}

那么如何将语言环境传递给Constraint?或者我应该以不同的方式实施它?

1 个答案:

答案 0 :(得分:1)

locale参数是Request对象的成员 但是,请求对象不是一直创建的(例如,在CLI应用程序中) 此解决方案允许您将验证与请求对象分离,并使您的验证可以轻松进行单元测试。

LocaleHolder是一个请求侦听器,它将在创建%locale%参数时保留,然后在触发事件时切换到请求区域设置。
注意:%locale%参数是config.yml中定义的默认参数

然后,验证者必须将此LocaleHolder作为构造函数参数,以便了解当前的区域设置。

services.yml

在此处,声明您需要的两项服务,LocaleHolder和验证器。

services:
    acme.locale_holder:
        class: Acme\FooBundle\LocaleHolder
        arguments:
            - "%locale%"
        tags:
            -
                name: kernel.event_listener
                event: kernel.request
                method: onKernelRequest

    acme.validator.no_badwords:
        class: Acme\FooBundle\Constraints\NoBadwordsValidator
        arguments:
            - @acme.locale_holder
        tags:
            -
                name: validator.constraint_validator
                alias: no_badwords

的Acme \ FooBundle \ LocaleHolder

use Symfony\Component\HttpKernel\Event\GetResponseEvent;

class LocaleHolder
{
    protected $locale;

    public function __construct($default = 'EN')
    {
        $this->setLocale($default);
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        $request = $event->getRequest();

        $this->setLocale($request->getLocale());
    }

    public function getLocale()
    {
        return $this->locale;
    }

    public function setLocale($locale)
    {
        $this->locale = $locale;
    }
}

的Acme \ FooBundle \约束

use Acme\FooBundle\LocaleHolder;

class ContainsNoBadwordsValidator extends ConstraintValidator
{
    protected $holder;

    public function __construct(LocaleHolder $holder)
    {
        $this->holder = $holder;
    }

    protected function getBadwords($locale = null)
    {
        $locale = $locale ?: $this->holder->getLocale();

        // ...
    }
}