2015-02-09 77 views
2

我有两个有关验证的问题。我在我的实体中使用了很多属性方法(getter)(更好的代码imho)。这是一个这样的实体:验证基于getter而不是属性的symfony集合

class Spec2Events implements ValueAssignable 
    { 
     private $values; 

     /** 
     * @return \Doctrine\Common\Collections\Collection 
     */ 
     public function getValues() 
     { 
      return $this->values; 
     } 

     /** 
     * @return \Doctrine\Common\Collections\Collection 
     */ 
     public function getCauseOfDeathValues() 
     { 
      $codPms=array(); 
      array_push($codPms,'Cause of death::Natural'); 
      array_push($codPms,'Cause of death::Bycatch'); 
      array_push($codPms,'Cause of death::Ship strike'); 
      array_push($codPms,'Cause of death::Predation'); 
      array_push($codPms,'Cause of death::Other'); 
      array_push($codPms,'Cause of death::Unknown'); 
      return $this->getValues()->filter(
       function($entry) use ($codPms) { 
        return in_array($entry->getPmdSeqno()->getName(), $codPms); 
       } 
      ); 
     } 
    } 

在这种情况下$ values是一个SpecimenValues(实现EntityValues)的集合。 ValueAssignables有一个EntityValues集合。

EntityValuesType类是任何实现EntityValues的类的表单。这个表格有一些文字或选择的孩子。

EntityValuesType形式被称为像这样:

$builder->add('causeOfDeathValues', 'collection', array('type' => new EntityValuesType($this->doctrine), 
    'options' => array('data_class' => 'AppBundle\Entity\SpecimenValues'), 
    'allow_delete' => true, 
    'delete_empty' => true 
)); //in order to check if using a class getter as a property works (fails) 
$builder->add('values', 'collection', array('type' => new EntityValuesType($this->doctrine), 
    'options' => array('data_class' => 'AppBundle\Entity\SpecimenValues'), 
    'allow_delete' => true, 
    'delete_empty' => true 
)); //in order to check if using a class member as a property works (works) 

Validation.yml为SpecimenValues看起来是这样的:

AppBundle\Entity\SpecimenValues: 
    properties: 
     pmdSeqno: 
       - NotBlank: ~ 
       - NotNull: ~ 
     s2eScnSeqno: 
       - NotBlank: ~ 
       - NotNull: ~ 
     description: 
       - Length: 
        min: 0 
        max: 250 
     value: 
       - NotBlank: ~ 
       - NotNull: ~ 
       - Length: 
        min: 1 
        max: 50 
     valueFlag: 
       - Length: 
        min: 0 
        max: 50 

的控制器是这样的:

public function newAction() 
    { 
     $observation = $this->prepareObservation(); 
     $form = $this->createForm(new ObservationsType($this->getDoctrine()), $observation); 
     return $this->render('AppBundle:Page:add-observations-specimens.html.twig', array(
      'form' => $form->createView() 
     )); 
    } 

    private function prepareObservation(){ 
     $observation = new Observations(); 
     $event = new EventStates(); 
     $observation->setEseSeqno($event); 

     $s2e = new Spec2Events(); 
     $event->setSpec2Events($s2e); 

     $this->instantiateSpecimenValues('Cause of death::Natural', $s2e, false); 
     $this->instantiateSpecimenValues('Cause of death::Bycatch', $s2e, false); 
     $this->instantiateSpecimenValues('Cause of death::Ship strike', $s2e, false); 
     $this->instantiateSpecimenValues('Cause of death::Predation', $s2e, false); 
     $this->instantiateSpecimenValues('Cause of death::Other', $s2e, false); 
     $this->instantiateSpecimenValues('Cause of death::Unknown', $s2e, false); 
//... 
     return $observation; 
    } 

    private function instantiateSpecimenValues($pmName, &$s2e, $mustBeFlagged) 
    { 
     $em = $this->getDoctrine()->getManager(); 
     $pm = $em->getRepository("AppBundle:ParameterMethods")->getParameterMethodByName($pmName); 
     $sv = new SpecimenValues(); 
     $sv->setPmdSeqno($pm); 
     $sv->setS2eScnSeqno($s2e); 
     $sv->setValueFlagRequired($mustBeFlagged); 
     return $sv; 
    } 

现在,我的问题在于空值不会被验证器阻止(不会显示任何表单错误消息)。

如果我编程方式添加验证限制在FormEvents :: PRE_SET_DATA,像这样:

$options2['constraints'] = array(new \Symfony\Component\Validator\Constraints\NotNull()); 

它的工作原理,但摆在.yml文件的限制被忽略。是否有可能结合做'编程'和validation.yml?无论如何,我会写一个回调来添加.yml,所以我更喜欢validation.yml。

使用名称为'values'的窗体子对应于纯类成员变量,其工作方式如下:所有必需的空字段都会获得一条消息。所有其他验证正常工作。

什么可以解决这个问题?我也可以使用“值”并使用树枝来分割集合,但我更喜欢使用方法作为属性访问器。

谢谢!

+0

是否还有其他的验证工作?您还可以在yware获取表单值时分享您的操作 – Baig 2015-02-09 14:51:41

+0

其他不相关的验证工作。 “价值”收集表单的验证也可以。 – 2015-02-09 15:32:21

回答

0

我已经解决了这个问题,只需创建字段既作为getters和作为属性。属性本身在setters中设置。这是必要的,否则验证器从不被调用。

所以:

/** 
* @var \Doctrine\Common\Collections\Collection 
* @ORM\OneToMany(targetEntity="AppBundle\Entity\SpecimenValues", mappedBy="s2eScnSeqno") 
*/ 
private $values; 

private $causeOfDeathValues; 

/** 
* @param \Doctrine\Common\Collections\Collection $values 
* @return Spec2Events 
*/ 
public function setCauseOfDeathValues(\Doctrine\Common\Collections\Collection $values) 
{ 
    $this->causeOfDeathValues=$values; 
    $this->values= new \Doctrine\Common\Collections\ArrayCollection(
     array_merge($this->getValues()->toArray(), $values->toArray()) 
    ); 
    return $this; 
}