对于那些使用依赖项本身进行表单验证的人来说,这会有所帮助。
我假设 Symfony 版本是 3.4 或 4.1,并且您的项目中有 symfony/form。
构建您的 CustomConstraintValidator
处理具有某种依赖关系的 Symfony 表单验证器的最佳方法是使用 CustomValidators
以上是我用来与他们合作的示例。
假设我们有一个像这样的实体
// src/Entity/myEntity.php
namespace App\Entity;
...
class myEntity
{
private $id;
private $name; // string, required
private $canDrive; // bool, not required (default=false)
private $driveLicense; // string, not required (default = null)
public function __construct()
{
$this->canDrive = false;
}
// getters and setters
}
我们不需要填充$driveLicense(因为该属性不是强制性的),但如果$canDrive从false更改为true,现在$driveLicense必须有一个值。
$driveLicense 依赖于 $canDrive。
要为此构建一个表单并在 FormType 上正确验证 $driveLicense(最佳实践),我们需要构建一个 CustomConstraintValidator。
构建 CanDriveValidator
// src/Validator/Constraints/CanDrive.php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
class CanDrive extends Constraint
{
public $message = 'invalid_candrive_args'; // I like translators :D
}
翻译文件 - 可选
//src/translators/validators.en.yaml //
invalid_candrive_args: When "{{ candrivelabel }} " field is checked you must fill "{{ drivelicenselabel }}"
验证器
// src/Validator/Constraints/CanDriveValidator.php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class CanDriveValidator extends ConstraintValidator
{
/**
* Checks if the passed value is valid.
*
* @param mixed $value The value that should be validated
* @param Constraint $constraint The constraint for the validation
*/
public function validate($value, Constraint $constraint)
{
$canDriveField = $this->context->getObject(); // the Field using this validator
$form = $canDriveField->getParent(); // the formType where the Field reside
$myEntity = $form->getData(); // The Entity mapped by formType
if ($myEntity->getCanDrive() == true && $myEntity->getDriveLicense() == null) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ candrivelabel }}', 'Can Drive')
->setParameter('{{ drivelicenselabel }}', 'Drive License')
->addViolation();
}
}
}
myEntityType 表单
//src/Form/myEntityType.php
namespace App\Form;
use App\Entity\myEntity;
use App\Validator\Constraints\CanDrive;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class myEntityType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name')
->add('canDrive', CheckBoxType::class, [
'required' => false,
'constraints' => array(new canDrive()),
]
)
->add('driveLicense', TextType::class, ['required' => false])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(['data_class' => myEntity::class]);
}
}
现在,当使用 myEntityType 表单的调用 isValid() 方法并检查 canDrive 字段并且 driveLicense 为空白时,将在 canDrive 字段上触发 Violation。如果 canDrive 设置为 false(未选中,未提交),则不会发生任何事情,并且即使 driveLicense 为空白,表单也会有效。