Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Symfony(2.7)——>;构建表单->;将表单中另一个字段的值传递给自定义约束_Php_Symfony_Symfony Forms - Fatal编程技术网

Php Symfony(2.7)——>;构建表单->;将表单中另一个字段的值传递给自定义约束

Php Symfony(2.7)——>;构建表单->;将表单中另一个字段的值传递给自定义约束,php,symfony,symfony-forms,Php,Symfony,Symfony Forms,我想将某个字段的值传递给另一个字段的自定义约束(->以便在自定义验证器中使用) 表单中包含一些字段: ... ->add('BsaKey', new \app\...\fieldTypes\RadioButtonType(), [ 'choices' => [ ... ], 'expanded' => true,

我想将某个字段的值传递给另一个字段的自定义约束(->以便在自定义验证器中使用)

表单中包含一些字段:

...
            ->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的自定义约束:

    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'])
            ]);
        }
    }
我怎样才能做到这一点

另外,我不是把Symfony作为一个整体来使用,只是一些独立的组件


编辑:

Thx,我找到了解决方案:

class MeteringCodeValidator extends \Symfony\Component\Validator\ConstraintValidator
{
    public function validate($value, \Symfony\Component\Validator\Constraint $constraint)
    {
       $BsaKey = $this->context->getRoot()->get('BsaKey')->getData();
       ...
    }
}

似乎独立于“getTargets()”函数返回的选项工作。

我使用一个。 我会检查一个字段是否大于另一个字段,请根据您的要求随意更改

样本代码

<?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);
    }
}

我用计算机做了一些类似的事情。 我会检查一个字段是否大于另一个字段,请根据您的要求随意更改

样本代码

<?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);
    }
}

尝试使“validate”-函数返回上下文类(任何不是当前字符串值的内容),但对我无效。尝试换行并发送消息。。。我注意到我试图使用“getTargets()”-函数获取对象作为“validate()”-function的第一个参数,但不起作用…试图使“validate”-函数返回上下文类(任何不包含当前字符串值的内容),但对我不起作用。试图换行并发送消息。。。我注意到我试图使用“getTargets()”-函数获取对象作为“validate()”-函数的第一个参数,但没有成功。。。