symfony2使用另一个表单值来验证表单值 [英] symfony2 validate a form value using another form value

查看:57
本文介绍了symfony2使用另一个表单值来验证表单值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Symfony2中,我使用自定义约束来验证表单上的某些数据,但我想知道是否可以从表单中引入一个值以用于验证另一个值?

In Symfony2, I use custom constraints to validate some data on my form, but I wonder if I can bring in one value from the form to use in validating another value?

这是我的约束...

<?php
// src\BizTV\ContainerManagementBundle\Validator\Constraints\ContainerExists.php
namespace BizTV\ContainerManagementBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class ContainerExists extends Constraint
{
    public $message = 'Namnet är upptaget, vänligen välj ett annat.';

    public function validatedBy()
    {
        return 'containerExists';
    }

}

还有我的验证人...

And my validator...

<?php 
// src\BizTV\ContainerManagementBundle\Validator\Constraints\ContainerExistsValidator.php
namespace BizTV\ContainerManagementBundle\Validator\Constraints;

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

use Symfony\Component\DependencyInjection\ContainerInterface as Container;
use Doctrine\ORM\EntityManager as EntityManager;

class ContainerExistsValidator extends ConstraintValidator
{

    private $container;
    private $em;

    public function __construct(Container $container, EntityManager $em) {
        $this->container = $container;
        $this->em = $em;
    }   

    public function isValid($value, Constraint $constraint)
    {

        $em = $this->em;
        $container = $this->container;

        $company = $this->container->get('security.context')->getToken()->getUser()->getCompany();

        //Fetch entities with same name
        $repository = $em->getRepository('BizTVContainerManagementBundle:Container');
        $query = $repository->createQueryBuilder('c')
            ->where('c.company = :company')
            ->setParameter('company', $company)
            ->orderBy('c.name', 'ASC')
            ->getQuery();
        $containers = $query->getResult();      

        foreach ($containers as $g) {
            if ($g->getName() == $value) {
                $this->setMessage('Namnet '.$value.' är upptaget, vänligen välj ett annat', array('%string%' => $value));
                return false;
            }
        }

        return true;
    }
}

通过服务使用...

services:
  biztv.validator.containerExists:
    class: BizTV\ContainerManagementBundle\Validator\Constraints\ContainerExistsValidator
    arguments: ['@service_container', '@doctrine.orm.entity_manager']      
    tags:
        - { name: validator.constraint_validator, alias: containerExists }

这是我将其应用到我的实体中的方式...

Here's how I apply it like this to my entity...

<?php

namespace BizTV\ContainerManagementBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

use BizTV\ContainerManagementBundle\Validator\Constraints as BizTVAssert;

use BizTV\UserBundle\Entity\User as user;
use BizTV\ContainerManagementBundle\Entity\Container as Container;

/**
 * BizTV\ContainerManagementBundle\Entity\Container
 *
 * @ORM\Table(name="container")
 * @ORM\Entity
 */
class Container
{

    /**
     * @var integer $id
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var string $name
     * @Assert\NotBlank(message = "Du måste ange ett namn") 
     * @BizTVAssert\ContainerExists
     * @ORM\Column(name="name", type="string", length=255, nullable=true)
     */
    private $name;

在我的验证器中,我希望能够完成类似的事情

In my validator I would like to be able to accomplish something like this instead

public function isValid($FORM->OTHERVALUE, $value, Constraint $constraint)
{

    $em = $this->em;
    $container = $this->container;

    $company = $this->container->get('security.context')->getToken()->getUser()->getCompany();

    //Fetch entities with same name
    $repository = $em->getRepository('BizTVContainerManagementBundle:Container');
    $query = $repository->createQueryBuilder('c')
        ->where('c.company = :company')
        ->setParameter('company', $company)
        ->orderBy('c.name', 'ASC')
        ->getQuery();
    $containers = $query->getResult();      


        if ($g->getName() == $FORM->OTHERVALUE) {
            $this->setMessage('Namnet '.$value.' är upptaget, vänligen välj ett annat', array('%string%' => $value));
            return false;
        }


    return true;
}

推荐答案

您可以创建类约束验证器(

You can create a Class Constraint Validator (http://symfony.com/doc/master/cookbook/validation/custom_constraint.html#class-constraint-validator) and with this you get the object itself.

首先,您需要创建一个Constraint类:

First you need to create a Constraint class:

class ContainerExists extends Constraint
{
    public $message = 'Namnet är upptaget, vänligen välj ett annat.';

    public function validatedBy()
    {
        return 'containerExists';
    }

    public function getTargets()
{
    return self::CLASS_CONSTRAINT;
}
}

之后,创建验证器本身,您可以在其中访问对象,而不仅仅是单个属性.

after that create the validator itself where you have access to the object and not only a single property.

class ContainerExistsValidator extends ConstraintValidator {

    private $em;
    private $security_context;

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

    public function validate($object, Constraint $constraint) {

        // do whatever you want with the object, and if something is wrong add a violation

                $this->context->addViolation($constraint->message, array('%string%' => 'something'));

            }

        }

    }

然后创建服务以访问实体管理器和内容:

then create the service to access entity manager and stuff:

validator.container_exists:
        class: YourBundleName\Validator\Constraints\ContainerExistsValidator
        arguments: ["@doctrine.orm.entity_manager", "@security.context"]
        tags:
            - { name: validator.constraint_validator, alias: containerExists }

在这种情况下,由于将类约束验证器应用于类本身,而不是应用于属性,因此您需要在类中添加以下注释.

In this case as the class constraint validator is applied to the class itself, and not to the property you need to add the following annotation to your class.

use YourBundleName\Validator\Constraints as BackendAssert;

/**
 * @BackendAssert\ContainerExists
 */

这篇关于symfony2使用另一个表单值来验证表单值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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