将自定义参数传递给 Symfony2 中的自定义 ValidationConstraint [英] Pass custom parameters to custom ValidationConstraint in Symfony2

查看:27
本文介绍了将自定义参数传递给 Symfony2 中的自定义 ValidationConstraint的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 Symfony2 中创建一个表单.该表单仅包含一个 book 字段,允许用户在 Books 实体列表之间进行选择.我需要检查所选的 Book 是否属于我的控制器中的 Author.

I'm creating a form in Symfony2. The form only contains one book field which allows the user to choose between a list of Books entities. I need to check whether the selected Book belongs to an Author I have in my controller.

public class MyFormType extends AbstractType
{
    protected $author;

    public function __construct(Author $author) {
        $this->author = $author;
    }

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add('book', 'entity', array('class' => 'AcmeDemoBundle:Book', 'field' => 'title');
    }

    // ...
}

我想在提交表单后检查所选的 Book 是否由我的控制器中的 $author 编写:

I want to check, after submitting the form, that the selected Book is written by the $author in my controller:

public class MyController
{
    public function doStuffAction() {
        $author = ...;
        $form = $this->createForm(new MyFormType($author));
        $form->bind($this->getRequest());

        // ...
    }
}

不幸的是,我找不到任何方法来做到这一点.我尝试按照 The Cookbook 中的说明创建自定义验证器约束,但是虽然我可以通过将验证器定义为服务来将 EntityManager 作为参数传递,我不能将 $author 从控制器传递给验证器约束.

Unfortunately, I cannot find any way to do that. I tried creating a custom validator constraint as explained in The Cookbook, but while I can pass the EntityManager as parameter by defining the validator as a service, I cannot pass the $author from the controller to the validator constraint.

class HasValidAuthorConstraintValidator extends ConstraintValidator
{
    private $entityManager;

    public function __construct(EntityManager $entityManager) {
        $this->entityManager = $entityManager;
    }

    public function validate($value, Constraint $constraint) {
        $book = $this->entityManager->getRepository('book')->findOneById($value);
        $author = ...; // That's the data I'm missing

        if(!$book->belongsTo($author))
        {
            $this->context->addViolation(...);
        }
    }
}

这个解决方案可能就是这样我一直在寻找,但我的表单没有绑定到实体,也不意味着(我从 getData() 方法获取数据).

This solution could be exactly the one that I was looking for, but my form is not bound to an Entity and is not meant to be (I'm getting the data from the getData() method).

我的问题有解决方案吗?这一定是个常见的情况,但我真的不知道如何解决.

Is there a solution to my problem ? This must be a common case but I really don't know how to solve it.

推荐答案

在 Cerad 的帮助下,我终于弄明白了.要注入需要从 ConstraintValidator::validate() 方法访问的自定义参数,您需要在 Constraint 中将它们作为 options 传递.

I finally figured it out, with the help from Cerad. To inject custom parameters that need to be accessed from the ConstraintValidator::validate() method, you need to pass them as options in the Constraint.

public class HasValidAuthorConstraint extends Constraint
{
    protected $author;

    public function __construct($options)
    {
        if($options['author'] and $options['author'] instanceof Author)
        {
            $this->author = $options['author'];
        }
        else
        {
            throw new MissingOptionException("...");
        }
    }

    public function getAuthor()
    {
        return $this->author;
    }
}

并且,在 ConstraintValidator 中:

And, in the ConstraintValidator:

class HasValidAuthorConstraintValidator extends ConstraintValidator
{
    private $entityManager;

    public function __construct(EntityManager $entityManager) {
        $this->entityManager = $entityManager;
    }

    public function validate($value, Constraint $constraint) {
        $book = $this->entityManager->getRepository('book')->findOneById($value);
        $author = $this->constraint->getAuthor();

        if(!$book->isAuthor($author))
        {
            $this->context->addViolation(...);
        }
    }
}

最后但并非最不重要的是,您必须将参数传递给验证器:

Last but not least, you have to pass the parameter to the Validator:

public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder->add('book', 'entity', array(
        'class' => 'AcmeDemoBundle:Book',
        'field' => 'title',
        'constraints' => array(
            new HasValidAuthorConstraint(array(
                'author' => $this->author
            ))
        )
    ));
}

这篇关于将自定义参数传递给 Symfony2 中的自定义 ValidationConstraint的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆