基于 getter 而不是属性验证 symfony 集合
Validating symfony collection based on getters instead of properties
我有 2 个关于验证的问题。我在我的实体中大量使用 属性 方法(吸气剂)(更好的代码恕我直言)。这是一个这样的实体:
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 class 是实现 EntityValues 的任何 class 的形式。此表单有一些文本或选项子项。
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 文件中的约束被忽略。是否可以将 'programmatically' 与 validation.yml 结合起来?无论如何我都会写一个回调来添加到 .yml 中,所以我更喜欢 validation.yml.
使用名称为 'values' 的子表单,对应于纯 class 成员变量,按预期工作:所有必需的空字段都会收到一条消息。所有其他验证工作正常。
有什么办法可以解决这个问题?我也可以使用 'values' 并使用 twig 来拆分集合,但我更喜欢将方法用作 属性 访问器。
谢谢!
我通过将字段创建为 getter 和属性来简单地解决了这个问题。属性本身在设置器中设置。这是必要的,否则永远不会调用验证器。
所以:
/**
* @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;
}
我有 2 个关于验证的问题。我在我的实体中大量使用 属性 方法(吸气剂)(更好的代码恕我直言)。这是一个这样的实体:
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 class 是实现 EntityValues 的任何 class 的形式。此表单有一些文本或选项子项。
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 文件中的约束被忽略。是否可以将 'programmatically' 与 validation.yml 结合起来?无论如何我都会写一个回调来添加到 .yml 中,所以我更喜欢 validation.yml.
使用名称为 'values' 的子表单,对应于纯 class 成员变量,按预期工作:所有必需的空字段都会收到一条消息。所有其他验证工作正常。
有什么办法可以解决这个问题?我也可以使用 'values' 并使用 twig 来拆分集合,但我更喜欢将方法用作 属性 访问器。
谢谢!
我通过将字段创建为 getter 和属性来简单地解决了这个问题。属性本身在设置器中设置。这是必要的,否则永远不会调用验证器。
所以:
/**
* @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;
}