2016-11-15 49 views
0

我正在使用一個實體,並且此實體繼承自另一個實體。除了一件事以外,一切工作都很好。似乎基本實體字段上的服務器端驗證是「丟失」的。實體繼承後約束驗證丟失

繼承類:

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

/** 
* TicketBase 
* @ORM\MappedSuperclass 
*/ 
class TicketBase 
{ 
    /** 
    * @var string 
    * 
    * @ORM\Column(name="title", type="string", length=255) 
    * @Assert\NotBlank() 
    */ 
    private $title; 

    /* other fields */ 

然後:

use AppBundle\Repository\TicketRepository; 
use Doctrine\ORM\Mapping as ORM; 

/** 
* Ticket 
* 
* @ORM\Table(name="cheval_ticket") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\TicketRepository") 
*/ 
class Ticket extends TicketBase 
{ 
    /* only specific fields here */ 

在那之後,我可以在我的票實體使用任何我TicketBase場沒有問題存在,但是當我創建票形式,我在Ticket :: title上沒有服務器端驗證,所以如果標題爲空,我會得到完整性約束違規。

我是否缺少一些能讓我的驗證工作?

感謝

編輯:

控制器動作:

/** 
* @Route("/tickets/{uniqid}/{contactId}", name="contact_tickets") 
*/ 
public function ticketsAction(Request $request, $contactId = null, $uniqid = null) 
{ 
    $em = $this->getDoctrine()->getManager(); 
    $contact = $em->getRepository("AppBundle:Contact") 
      ->findOneBy(array(
     'id' => $contactId, 
     'uniqid' => $uniqid 
    )); 

    if ($contact === null) { 
     return $this->go('contact_index'); 
    } 

    $form = $this 
      ->createForm(ContactTicketsType::class, $contact, ['method' => 'POST']) 
      ->handleRequest($request); 

    if ($form->isSubmitted() && $form->isValid()) { 
     $this->setTicketsPrice($contact); 
     $this->setTicketsNbJours($contact); 
     $this->save($contact); 
     $this->setTicketsCodeId($contact); 
     return $this->go('payement_index', [ 
        'contactId' => $contact->getId(), 
        'uniqid' => $contact->getUniqid(), 
         ] 
     ); 
    } 
} 

我接觸實體有票務這種關係:

/** 
* @ORM\OneToMany(targetEntity="Ticket", mappedBy="contact", cascade={"remove", "persist"}) 
*/ 
private $tickets; 

而且我ContactTicketsType:

namespace AppBundle\Form\Type\Contact; 

use AppBundle\Form\Type\Ticket\TicketType; 
use AppBundle\Form\Type\Ticketadd\TicketaddType; 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\Extension\Core\Type\CollectionType; 
use Symfony\Component\Form\Extension\Core\Type\SubmitType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 

/** 
* Description of ContactType 
*/ 
class ContactTicketsType extends AbstractType 
{ 

    /** 
    * 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
       ->add('tickets', CollectionType::class, array(
        'entry_type' => TicketType::class, 
        'allow_add' => true, 
        'allow_delete' => true, 
        'label' => false, 
        'by_reference' => false 
       )) 
       // ... 
     ; 

    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'AppBundle\Entity\Contact' 
     )); 
    } 

} 

回答

0

我需要手動添加在我收集的驗證,因爲cascade_validation已在symfony中3被刪除,這樣的:

$builder 
       ->add('tickets', CollectionType::class, array(
        'entry_type' => TicketType::class, 
        'allow_add' => true, 
        'allow_delete' => true, 
        'label' => false, 
        'by_reference' => false 
       )) 
1

它可能來自你宣佈你的$ title屬性爲private而不是protected。

讓我們採取以下爲例:

class Foo 
{ 
    private $property; 

    public function getProperty() 
    { 
     if (null === $this->property) 
     { 
      return 'foo'; 
     } 
     return $this->property; 
    } 
} 

class Bar extends Foo 
{ 
    public function __construct() 
    { 
     $this->property = 'bar'; 
    } 
} 

$child = new Bar(); 

echo $child->getProperty(); 

此代碼將返回「富」,因爲$屬性不是從類Foo繼承這樣的構造方法實際上什麼也不做。但是,如果我們改變

private $property; 

protected $property; 

然後

echo $child->getProperty(); 

會顯示 '酒吧'

編輯:

你問題實際上來自嵌入的Ticket FormType而不是繼承。據this question您必須啓用cascade_validation參數上您的聯繫FormType

public function configureOptions(OptionsResolver $resolver) 
{ 
    $resolver->setDefaults(array(
     'data_class' => 'AppBundle\Entity\Contact', 
     'cascade_validation' => true 
    )); 
} 

否則只有你聯繫的實體將被驗證。

+0

這是有道理的,很明顯,但我改變了我的屬性,以保護並具有完全相同的結果...順便說一句,即使我的標題屬性是私人的,我可以通過我的擴展實體訪問和修改它......我不明白髮生了什麼問題。 – ThEBiShOp

+0

您是否嘗試在getTitle方法上設置驗證器? 像[Symfony文檔](https://symfony.com/doc/2.7/validation.html#getters)中所述 – OlivierC

+0

我剛試過但沒有改變 – ThEBiShOp