标题可能看起来很尴尬,但这样做的原因是重复使用代码。
假设我有一个表单(类型),一个实体以及对实体的验证作为注释。
例如:
表单:
$form = $this->createFormBuilder($entity)
->add('country', 'choice', [
'choices' => $entity->getLocations(),
'required' => true,
'multiple' => false,
'expanded' => false,
'label' => 'Are you located in:',
])
实体:
/**
* @Assert\Choice(callback = "getLocations")
*/
protected $country;
#.....
public static function getLocations()
{
return array( 'en-wa' => 'England/Wales', 'sc' => 'Scotland');
}
现在验证将始终失败,因为它使用值而不是键,所以我想写一个名为KeyChoice的自定义验证器,所以我仍然可以使用回调。但我似乎无法找到任何关于此的文档,阅读源代码也没有帮助。
现在我不想要对最佳实践做出判断,除非有一种方法我只需要定义选项1 /表格甚至更少,例如在表单类型中,但是我如何使用它们在验证器的回调中?
答案 0 :(得分:1)
这个怎么样:
/**
* @Assert/Choice(callback="getLocationChoices")
*/
...
public static function getLocationChoices(){
return array_keys(self::getLocations());
}
或者您可以为此创建custom constraint:
// the constraint
namespace AppBundle\Constraints;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class KeyChoice extends Constraint
{
public $message = 'the choice is not valid';
public $callback;
}
// the validator
namespace AppBundle\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
class KeyChoiceValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
if (!is_callable($choices = array($this->context->getClassName(), $constraint->callback))
&& !is_callable($choices = $constraint->callback)
) {
throw new ConstraintDefinitionException('The Choice constraint expects a valid callback');
}
$choices = call_user_func($choices);
if(!in_array($value, $choices)){
$this->context->buildViolation($constraint->message)->addViolation();
}
}
}
然后您可以使用链接文档中所述的此约束。但是,如果您想要扩展两者,则不会提供选择约束提供的任何其他功能。 Symfony\Component\Validator\Constraints\Choice
和Symfony\Component\Validator\Constraints\ChoiceValidator
,请勿覆盖ChoiceConstraint
中的任何内容,但您必须完全覆盖ChoiceConstraintValidator::validate
并复制粘贴,然后添加$choices = array_keys($choices);
this line