2012-09-04 17 views
27

同じクラスの別のプロパティに依存するモデルクラスのプロパティを検証できますか?例えばSymfony 2の別のプロパティに依存するプロパティを検証する方法

、私はこのクラスがあります。

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

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

を、私は$startDate$endDate後になければならないこと、symfonyは2.0検証する必要。

これはアノテーションで可能ですか、それとも手動で行う必要がありますか?

答えて

19

コールバックバリではい:私はたstartDateフィールドにエラーメッセージを表示するように選択

ここ
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); 
     } 
    } 

:symfonyの2.0オンhttp://symfony.com/doc/current/reference/constraints/Callback.html

:symfonyのマスターバージョンで

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

+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を使用すると、さらに複雑な検証をいつでも行うことができます。

class Conference 
{ 
    //... 

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

    //... 
} 

参照、documentationとおり

10

別の方法は、(少なくとも 2.3 symfonyののような)単純な@Assert\IsTrueを使用することです。

+1

@Assert \ TrueはSymfony 2.0以降にありましたが、Symfony 2.3の@Assert \ IsTrueを使用してください。 –

+0

@DanielP:はい、2.3に '@Assert \ IsTrue'を追加しました。 '@Assert \ True'は2.7から廃止されました。更新しました、ありがとうございます。 – Nevertheless

関連する問題