我创建了需要数据转换器的表单,但陷入一个单一问题:我通过爆炸字符串(应将字符串爆炸为3部分)来转换数据,如果我提供正确的格式字符串,则一切正常,但否则会在数据内部引发错误转换器,因为如果提供了错误的字符串格式,则转换不会发生(这是预期的行为)。
因此,问题是在数据转换之前是否有一种方法可以验证表单字段中的正确字符串?我知道默认情况下会在验证之前进行数据转换,但是也许有其他方法可以做到?
我找到了一个可能在此线程上工作的解决方案:Combine constraints and data transformers,
但这似乎是一个粗略的解决方案,除了我需要翻译验证消息,而且我真的很想使用针对symfony表单的默认翻译方法来进行翻译(不使用翻译服务)
我以为,还有来自symfony IRC(Iltar)的某人建议通过使用事件来做到这一点,但我不确定该如何处理-如何动态地将数据转换器附加到表单字段上?也许还有其他方法?
最佳答案
也许为时已晚,但我最终设法做到了。
也许会对您有帮助。
这是我的FormType:
class PersonType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options){
$builder->add('mother', 'personSelector', array('personEntity' => $options['personEntity']));
}
}
这是我的customField验证所在的位置:
class PersonSelectorType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options){
$transformer = new PersonByFirstnameAndLastnameTransformer($this->entityManager,$options);
$builder->addModelTransformer($transformer);
$builder->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'onPreSubmitForm'));
}
public function onPreSubmitForm(FormEvent $event){
$mother = $event->getData();
$form = $event->getForm();
$options = $form->getConfig()->getOptions();
if (!empty($mother)){
preg_match('#(.*) (.*)#', $mother, $personInformations);
if (count($personInformations) != 3){
$form->addError(new FormError('[Format incorrect] Le format attendu est "Prénom Nom".'));
}else{
$person = $this->entityManager->getRepository($options['personEntity'])->findOneBy(array('firstname' => $personInformations[1],'lastname' =>$personInformations[2]));
if ($person === null) {
$form->addError(new FormError('Il n\'existe pas de person '.$personInformations[1].' '.$personInformations[2].'.'));
}
}
}
}
}
这是我的变压器:
class PersonByFirstnameAndLastnameTransformer implements DataTransformerInterface{
public function reverseTransform($firstnameAndLastname) {
if (empty($firstnameAndLastname)) { return null; }
preg_match('#(.*) (.*)#', $firstnameAndLastname, $personInformations);
$person = $this->entityManager->getRepository($this->options['personEntity'])->findOneBy(array('firstname' =>$personInformations[1],'lastname' =>$personInformations[2]));
if (count($personInformations) == 3){
$person = $this->entityManager->getRepository($this->options['personEntity'])->findOneBy(array('firstname' =>$personInformations[1],'lastname' =>$personInformations[2]));
}
return $person;
}
public function transform($person) {
if ($person === null) { return ''; }
return $person->getFirstname().' '.$person->getLastname();
}
}