我是一个Symfony noob尝试无法成功地根据它或不同的字段来验证表单字段的验证方法。案件:表格将征求出生日期或年龄。如果输入dob,则忽略年龄。如果输入年龄且dob为空,则称dob是今天的年龄,而不是年龄。如果两者都未输入,则抛出验证错误。我用Smarty验证完成了这个;作为一个学习练习,我试图在Symfony中重现该应用程序。
我查看了this solution,其中两个字段都是实体的属性。在我的情况下,年龄不是,只有dob。所以我不清楚如何应用该解决方案。我非常感谢指针。
感谢。
乔治 PS :(编辑:dreck删除) PPS :(编辑:删除为近乎工作版本腾出空间) 形式:
// src\Mana\AdminBundle\Resources\views\Form\Type\NewClientType.php
namespace Mana\AdminBundle\Form\Type;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Mana\AdminBundle\Validator\Constraints;
class NewClientType extends AbstractType {
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array('validation_groups' => 'client_new',
'validation_constraint' => new DOBorAge(),
));
}
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('fname', null, array('required' => false));
$builder->add('sname', null, array('required' => false));
$builder->add('dob', 'birthday', array('widget' => 'single_text', 'required' => false));
$builder->add('age', null, array('mapped' => false, 'required' => false));
}
public function getName() {
return 'client_new';
}
}
服务:
services:
client_new:
class: Mana\AdminBundle\Validator\Constraints\DOBorAgeValidator
scope: request
tags:
- { name: validator.constraint_validator, alias: dobage_validator}
校验:
// src\Mana\AdminBundle\Form\Type\DOBorAge.php
namespace Mana\AdminBundle\Form\Type;
use Mana\AdminBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
class DOBorAge extends Constraint {
public $message = 'Either a date of birth or age must be present';
public function validatedBy() {
return 'dobage_validator';
}
public function getTargets() {
return Constraint::CLASS_CONSTRAINT;
}
}
和
// src\Mana\AdminBundle\Validator\Constraints\DOBorAgeValidator.php
namespace Mana\AdminBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class DOBorAgeValidator extends ConstraintValidator {
protected $request;
public function __construct(Request $request) {
$this->request = $request;
}
public function validate($value, Constraint $constraint) {
var_dump($this->request->request->get('client'));
die();
return true;
}
}
答案 0 :(得分:1)
我认为管理此类验证的最佳方法是在表单中添加customized validation constraint。
只需添加一个扩展Symfony\Component\Validator\Constraint
的类并覆盖validatedBy()
方法。然后,您可以指定要创建的自定义验证器,以便它包含表单验证的所有逻辑。
此自定义验证程序应扩展Symfony\Component\Validator\ConstraintValidator
类,并为Symfony 2.1.x实现isValid()
方法或为Symfony 2.1.x实现validate()
方法。
然后,您可以检查您的值,比较它们并在此方法中执行您想要的任何操作,并在不遵守一个或多个验证规则时添加最终添加违规。
答案 1 :(得分:1)
Symfony-esque解决方案:采用日期或年龄的单个表单字段,然后将条目转换为日期。 (现在,如果我只能将其变成自定义字段......)
namespace Mana\AdminBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Mana\AdminBundle\Form\DataTransformer\AgeToDOB;
class NewClientType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$transformer = new AgeToDOB();
$builder->add('fname', null, array('required' => false,
'invalid_message' => 'First name not be blank',));
$builder->add('sname', null, array('required' => false,
'invalid_message' => 'Last name not be blank',));
$builder->add(
$builder->create('dob', 'text', array('required' => false,
))->addModelTransformer($transformer));
}
public function getName() {
return 'client_new';
}
}
和变压器:
namespace Mana\AdminBundle\Form\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Mana\AdminBundle\Entity\Client;
class AgeToDOB implements DataTransformerInterface {
public function reverseTransform($dob) {
if (null == $dob) {
return '';
}
if ((substr_count($dob, '/') == 2 && strtotime($dob))) {
$date = new \DateTime($dob);
return date_format($date, 'Y-m-d');
}
if (is_numeric($dob)) {
$date = new \DateTime();
$interval = 'P' . $dob . 'Y';
$date->sub(new \DateInterval($interval));
return date_format($date, 'Y-m-d');
}
}
public function transform($client) {
if (null == $client) {
return '';
}
if (is_object($client)) {
$dob = $client->getDob();
// date: test for two / characters
if ((substr_count($dob, '/') == 2 && strtotime($dob))) {
$date = new \DateTime($dob);
return date_format($date, 'm/d/Y');
}
if (is_numeric($dob)) {
$date = new \DateTime();
$interval = 'P' . $dob . 'Y';
$date->sub(new \DateInterval($interval));
return date_format($date, 'm/d/Y');
}
}
}
}