我想将某个字段的值传递给另一个字段的自定义约束( - >在自定义验证程序中使用它)
表格包含一些字段:
...
->add('BsaKey', new \app\...\fieldTypes\RadioButtonType(), [
'choices' => [
...
],
'expanded' => true,
'multiple' => false,
...
])
->add('MeteringCodes', 'collection', [
'type' => new \app\...\formTypes\MeteringCodeType(),
'allow_add' => true,
'label' => false,
'options' => ['label' => $this->lang->get('MeteringCode.Caption')],
'constraints' => new \app\...\validators\NoIdenticMeteringCodes()
])
...
现在我需要将BsaKey的值传递给MeteringCodeType的自定义Constraint:
class MeteringCodeType extends \Symfony\Component\Form\AbstractType
{
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder, array $options)
{
$builder->add('meteringCode', 'text', [
'...' => '...',
'constraints' => new \app\...\MeteringCodeConstraint(['param' => 'VALUE_OF_BsaKey'])
]);
}
}
我怎样才能实现这个目标?
P.S。我不是整个Symfony,只是一些独立的组件......
编辑:
谢谢,我找到了解决方案:
class MeteringCodeValidator extends \Symfony\Component\Validator\ConstraintValidator
{
public function validate($value, \Symfony\Component\Validator\Constraint $constraint)
{
$BsaKey = $this->context->getRoot()->get('BsaKey')->getData();
...
}
}
似乎独立于“getTargets()”函数返回的选项。
答案 0 :(得分:0)
我使用custom constraint做了类似的事情。 我检查一个字段比另一个字段大,可以随意根据您的要求进行更改。
示例代码;
<?php
// src/AppBundle/Validator/Constraints/FieldCompare.php
namespace AppBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class FieldCompare extends Constraint
{
/**
* Error Message
* @access public
* @var string - with placeholders [field1,field2]
*/
public $message = 'Field field2 must be greater than field1 ';
/**
* Form fields
* @access public
* @var array
*/
public $fields = array();
/**
* Class accessors (getters) for the fields.
* @access public
* @var array
*/
public $properties = array();
/**
* Error Path
* @var string
*/
public $errorPath;
public function __construct($options = null)
{
parent::__construct($options);
// check fields is an array
if (!is_array($this->fields) && !is_string($this->fields)) {
throw new UnexpectedTypeException($this->fields, 'array');
}
// make sure there are two of them
if (2 != count($this->fields)) {
throw new ConstraintDefinitionException("Two fields must be specified.");
}
// make sure they are strings
foreach ($this->fields as $f) {
if (null !== $this->errorPath && !is_int()) {
throw new UnexpectedTypeException($this->errorPath, 'integer or null');
}
}
}
/**
* getTargets()
*
* Set traget (so can be used against the class).
* @access public
* @return type
*/
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
}
<?php
// src/AppBundle/Validator/Constraints/FieldCompareValidator.php
namespace AppBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class FieldCompareValidator extends ConstraintValidator {
public function validate($protocol, Constraint $constraint)
{
$fields = (array) $constraint->fields;
$properties = (array) $constraint->properties;
if ($protocol->$properties[0]() >= $protocol->$properties[1]()) {
$this->context->addViolationAt($fields[1], $constraint->message,
array(
'field1' => $this->prettyField($fields[0]),
'field2' => $this->prettyField($fields[1])
), null);
}
}
private function prettyField($field)
{
if (strstr($field, '_')) {
$pretty = str_replace('_', ' ', $field);
} else {
// is camelCase
$converted = preg_replace('/(?!^)[[:upper:]]+/',' \0', $field);
if (is_array($converted)) {
$pretty = implode(' ', $converted);
} else {
$pretty = $converted;
}
}
return ucwords($pretty);
}
}
以下是我如何使用验证器(yaml格式);
AppBundle\Model\Foo:
constraints:
- AppBundle\Validator\Constraints\FieldCompare:
fields: [min_lead_time, max_lead_time]
properties: [getminLeadtime, getmaxLeadtime]
groups: [add]