2012-09-04 83 views
27

是否可以驗證依賴於同一類的另一個屬性的模型類的屬性?如何驗證依賴於Symfony 2中另一個屬性的屬性

例如,我有這個類:

class Conference 
{ 
    /** $startDate datetime */ 
    protected $startDate; 

    /** $endDate datetime */ 
    protected $endDate; 
} 

,我想那Symfony的2.0只會驗證,該$startDate必須$endDate後。

這是可能的註釋還是我必須手動執行此操作?

回答

19

是與回調驗證:http://symfony.com/doc/current/reference/constraints/Callback.html

在symfony的2.0:

use Symfony\Component\Validator\Constraints as Assert; 
use Symfony\Component\Validator\ExecutionContext; 

/** 
* @Assert\Callback(methods={"isDateValid"}) 
*/ 
class Conference 
{ 

    // Properties, getter, setter ... 

    public function isDateValid(ExecutionContext $context) 
    { 
     if ($this->startDate->getTimestamp() > $this->endDate->getTimestamp()) { 
       $propertyPath = $context->getPropertyPath() . '.startDate'; 
       $context->setPropertyPath($propertyPath); 
       $context->addViolation('The starting date must be anterior than the ending date !', array(), null); 
     } 
    } 
} 

在symfony的主版本:

public function isDateValid(ExecutionContext $context) 
    { 
     if ($this->startDate->getTimestamp() > $this->endDate->getTimestamp()) { 
      $context->addViolationAtSubPath('startDate', 'The starting date must be anterior than the ending date !', array(), null); 
     } 
    } 

在這裏,我選擇顯示在起始日期字段中的錯誤信息。

+0

標記@Psykehoe的答案應該是一個評論,而不是一個答案,因此在這裏重新評述他的評論。 'addViolationAtSubPath'從版本2.2開始已被棄用,請改用[addViolationAt](http://api.symfony.com/2.3/Symfony/Component/Validator/ExecutionContextInterface.html#method_addViolationAt)。 – astorije

9

自從version 2.4以來就更加簡單了。所有你需要做的就是這種方法添加到您的類:

use Symfony\Component\Validator\Context\ExecutionContextInterface; 

/** 
* @Assert\Callback 
*/ 
public function isStartBeforeEnd(ExecutionContextInterface $context) 
{ 
    if ($this->getStartDate() <= $this->getEndDate()) { 
     $context->buildViolation('The start date must be prior to the end date.') 
       ->atPath('startDate') 
       ->addViolation(); 
    } 
} 

buildViolation method回報有幾個其他的方法來幫助您配置的限制(如參數和翻譯)的生成器。

36

開始Symfony 2.4您還可以使用Expression驗證約束來實現您所需要的。我確實相信,這是做這件事最簡單的方法。肯定比回調約束更方便。

這裏的例子,你如何可以驗證約束註釋更新模型類:

use Symfony\Component\Validator\Constraints as Assert; 


class Conference 
{ 
    /** 
    * @var \DateTime 
    * 
    * @Assert\Expression(
    *  "this.startDate <= this.endDate", 
    *  message="Start date should be less or equal to end date!" 
    *) 
    */ 
    protected $startDate; 

    /** 
    * @var \DateTime 
    * 
    * @Assert\Expression(
    *  "this.endDate >= this.startDate", 
    *  message="End date should be greater or equal to start date!" 
    *) 
    */ 
    protected $endDate; 
} 

不要忘記enable annotations在你的項目配置。

通過使用expression syntax,您始終可以執行更復雜的驗證。

10

的另一種方式(至少Symfony的2.3的)是使用簡單@Assert\IsTrue

class Conference 
{ 
    //... 

    /** 
    * @Assert\IsTrue(message = "Startime should be lesser than EndTime") 
    */ 
    public function isStartBeforeEnd() 
    { 
     return $this->getStartDate() <= $this->getEndDate; 
    } 

    //... 
} 

作爲參考,documentation

+1

@Assert \自從Symfony 2.0開始,True就已經出現了,但是你應該使用來自Symfony 2.3的@Assert \ IsTrue –

+0

@DanielP:是的,2.3添加了'@Assert \ IsTrue'。 '@Assert \ True'從2.7開始棄用。更新,謝謝。 – Nevertheless