4

我有一个带有一些自定义验证器的实体,如下所示:

use Digital\ApplicationBundle\Validator\Constraints\ConstrainsUsername;
use Digital\ApplicationBundle\Validator\Constraints\ConstrainsProduct;
use Digital\ApplicationBundle\Validator\Constraints\ConstrainsGiftValid;

/**
 * @DigitalAssert\ConstrainsGiftValid
 */
class Gift
{

/**
 * @DigitalAssert\ConstrainsUsername
 */
private $username;

/**
 * @DigitalAssert\ConstrainsProduct
 */
private $productName;
[...]

我的问题是如何设置检查顺序....

我想先验证我的属性,如果属性有效,那么我想检查这两个属性是否允许“存在”在一起......

所以我的案例需要验证器的特定顺序。

请问这怎么可能实现?

当前的问题是我的班级验证“ConstrainsGiftValid”在他们之前开始;S

非常感谢任何帮助。

4

2 回答 2

1

要检查是否$username$productName在一起,您必须创建一个自定义验证约束

如果您需要验证器的特定顺序,并希望稍后在代码中重用这两个字段的验证,我认为应该这样做:

1为 {username and productName} 创建一个表单类型。

2在该 formType 上应用您的验证规则。如果您想使用验证顺序,则需要在这种特殊情况下对整个表单应用约束。因此,您只能按照您想要的顺序抛出错误。

3您最终可以将其嵌入到formType您的GiftFormType. 不要忘记使用有效约束或设置cascade_validation选项true来验证嵌入的表单。

于 2013-02-11T23:18:48.717 回答
1

好的,在一个约束中处理所有内容都有效。

这包括将错误绑定到特定属性,以及针对不同的故障报错不同的消息:

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

    // Validate product.
    /** @var $product Product */
    $product = $this->em->getRepository('DigitalApplicationBundle:Shop\Product')->findOneBy(array('name' => $gift->getProductName()));
    if (!$product instanceof Product) {

        $this->context->addViolationAtSubPath('username', $constraint->messageProduct, array('%string%' => $gift->getProductName()), null);
        return false;

    }

    // Validate user.
    /** @var $user User */
    $user = $this->em->getRepository('DigitalUserBundle:User')->findOneBy(array('username' => $gift->getUsername()));
    if (!$user instanceof User) {

        $this->context->addViolationAtSubPath('username', $constraint->messageUser, array('%string%' => $gift->getUsername()), null);
        return false;
    }


    // Gift correct type of the item!
    if (($product->getType() != 0) && ($user->getGender() !== $product->getType())) {

        $this->context->addViolationAtSubPath('username', $constraint->messageType, array('%string%' => $gift->getProductName()), null);
        return false;

    }

    // If already owning this product.
    foreach ($user->getWardrobe()->getProducts() as $wardrobeProduct) {
        if ($product == $wardrobeProduct) {

            $this->context->addViolationAtSubPath('username', $constraint->message, array('%string%' => $gift->getProductName(), '%user%' => $gift->getUsername()), null);
            return false;
        }
    }

    return true;
}
于 2013-02-12T00:19:52.340 回答