2

我需要针对坏词词典(例如数组)验证表单字段。所以要做到这一点,我必须创建一个新的 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;
        }
    }

}

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

4

1 回答 1

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\Constraints

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();

        // ...
    }
}
于 2013-08-22T14:54:31.957 回答