我解决了我的问题,我只想分享我的解决方案。
一种可能的解决方案是使用回调约束。例如,按照问题中提供的标签列表示例:
/**
* @Assert\Callback(methods={"isTagStringValid"})
*/
class AFormModel{
protected $tags;
public function isTagStringValid(ExecutionContext $context){
$tagsExploded = explode(',', $this->tags);
if(count($tagsExploded)==0){
$context->addViolationAtSubPath('tags', 'Insert at least a tag', array(), null);
}
if(count($tagsExploded)==1 && $tagsExploded[0]==='')
$context->addViolationAtSubPath('tags', 'Insert at least a tag', array(), null);
}
else if(count($tagsExploded)>10){
$context->addViolationAtSubPath('tags', 'Max 10 values', array(), null);
}
}
}
一种更优雅的方式是定义“令牌”验证器。下面是一个示例:
namespace .....
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class Token extends Constraint {
public $min;
public $max;
public $minMessage = '{{ min }} token(s) are expected';
public $maxMessage = '{{ max }} token(s) are expected';
public $invalidMessage = 'This value should be a string.';
public $delimiter = ',';
public function __construct($options = null){
parent::__construct($options);
if (null === $this->min && null === $this->max) {
throw new MissingOptionsException('Either option "min" or "max" must be given for constraint ' . __CLASS__, array('min', 'max'));
}
}
}
验证器类是:
namespace ...
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class TokenValidator extends ConstraintValidator {
public function isValid($value, Constraint $constraint) {
if ($value === null) {
return;
}
if(!is_string($value)){
$this->context->addViolation($constraint->invalidMessage, array(
'{{ value }}' => $value,
));
return;
}
$tokensExploded = explode($constraint->delimiter, $value);
$tokens = count($tokensExploded);
if($tokens==1){
if($tokensExploded[0]==='')
$tokens = 0;
}
if (null !== $constraint->max && $tokens > $constraint->max) {
$this->context->addViolation($constraint->maxMessage, array(
'{{ value }}' => $value,
'{{ limit }}' => $constraint->max,
));
return;
}
if (null !== $constraint->min && $tokens < $constraint->min) {
$this->context->addViolation($constraint->minMessage, array(
'{{ value }}' => $value,
'{{ limit }}' => $constraint->min,
));
}
}
}
通过这种方式,您可以导入用户定义的验证器并在任何地方使用它,就像我在问题中提出的那样。