2017-02-13 52 views
1

在我的Symfony項目中,我有一個實體Booking,其中包含另一個實體Traveler的集合。有1人,最多4人。旅客的數量可以由Booking實體的字段travelerCount指定。手動調用嵌入式表單集合條目的驗證

class Booking { 
    /** @Assert\Range(min = 1, max = 4) */ 
    private $travelerCount; 

    private $travelers = array(); 

    // ... 
} 

我的預訂表單控制器總是爲實體添加4位遊客。我的表格BookingType包含TravelerType表單的嵌入表單集合(CollectionType)。視圖中的JavaScript會根據travelerCount的值顯示或隱藏旅行者。

通常我會使用@Assert\Valid來驗證旅行者集合。但是這在這裏不起作用,因爲我只想驗證集合的第一個條目。例如,如果用戶指定的travelerCount爲2,則我無法驗證Traveler的第3和第4步。否則,由於Traveler中的@Assert\NotBlank註釋會出現驗證錯誤。

class Traveler { 
    /** @Assert\NotBlank */ 
    private $firstName; 

    // ... 
} 

所以我的想法是不使用@Assert\Valid。但是,我如何手動調用控制器嵌入式表單集合條目的驗證?我想過這樣的事情:

for ($i = 0; $i < $booking->getTravelerCount(); ++$i) { 
    $this->get('validator')->startContext() 
     ->atPath('booking.travelers['. $i .']') 
     ->validate($booking->getTravelers()[$i]); 
} 

但我不知道,這是否會令出現在視圖中的錯誤,也沒有哪個參數值傳遞給atPath()(我只是猜以上,但我敢肯定,我」米錯)。

+0

如何創建一個[自定義驗證器](http://symfony.com/doc/current/validation/custom_constraint.html)? – LBA

+0

我可以做到這一點,但它導致我有同樣的問題:我如何告訴Symfony驗證這些實體?我可以自己做空白檢查並手動添加違規,但我不想。我想通過它的驗證約束條件註釋來調用整個'Traveler'實體的驗證。 – fishbone

+0

'@Assert \ Valid'會根據旅行者的約束條件來驗證所有的旅行者,其中一個約束條件可能是一個自定義驗證,這也可以取決於其父母預訂的數量。但說實話,我猜這在這裏甚至不需要。 – LBA

回答

0

在我的問題的意見,LBA建議使用自定義驗證程序,我告訴他,我有同樣的問題:我不知道如何調用Traveler的驗證約束註釋的驗證。那麼,我發現如何:

class BookingValidator extends Symfony\Component\Validator\ConstraintValidator 
{ 
    public function validate($booking, Symfony\Component\Validator\Constraint $constraint) 
    { 
     for ($i = 0; $i < $booking->getTravelerCount(); ++$i) { 
      $this->context->getValidator()->inContext($this->context) 
       ->atPath('travelers['. $i .']') 
       ->validate($booking->getTravelers()[$i]) 
       ; 
     } 
    } 
} 

正如你可以看到代碼看起來類似於我的問題。但是,我沒有找到在控制器中執行此操作的方法。但同時,我認爲無論如何,在單獨的課程中驗證是更好的風格。