Может ли реализовать динамическую проверку на уровне элемента?

Может ли реализовать динамическую проверку на уровне элемента? я использовал этот Пример для реализации проверки одного элемента в зависимости от значения другого элемента. Но для этого мне нужно будет реализовать это для каждой формы, где я использую этот элемент (комментарий) с этой проверкой. У меня много таких форм. Есть ли способ сделать следующее:

перевести эту логику фильтра / проверки на уровень элемента, используя некоторый атрибут «data-comment-for» и извлекая значение элемента, от которого оно зависит, от родительской формы.

Это мой текущий код (но мне нужно иметь его для каждой формы. Он не выглядит элегантно):

class CompetencyAdvanceHumanRightsAndJusticeFormFilter extends InputFilter
{
public function isValid($context = null)
{
$figradeCommentName = 'applJusticeFIGrade'.'Comment';

$forGrade = $this->get('applJusticeFIGrade');
$gradeComment = $this->get($figradeCommentName);

$applJusticeFIGradeRawValue = $forGrade->getRawValue('applJusticeFIGrade');

if(is_numeric($applJusticeFIGradeRawValue)){
$gradeValue = intval($applJusticeFIGradeRawValue);
}else{
$gradeValue = $applJusticeFIGradeRawValue;
}

if ($gradeValue != 'na' && $gradeValue > 0) {
$gradeComment->setRequired(true);
$validatorChain = new Validator\ValidatorChain();
$validatorChain->attach(
new Validator\NotEmpty(),
true
);
$gradeComment->setValidatorChain($validatorChain);
}

return parent::isValid($context);
}

public function __construct(){
$this->add(array(
'name' => 'id',
'required' => true,
'filters' => array(
array('name' => 'Int'),
),
));

$this->add(array(
'name' => 'studEvalId',
'required' => true,
'filters' => array(
array('name' => 'Int'),
),
));
}
}

РЕДАКТИРОВАТЬ:

Я добавил код для пользовательского элемента в вопрос. Есть некоторые «остатки» моих попыток поместить эту логику на уровень элемента.

Элемент комментария

class Comment extends Element implements InputProviderInterface
{

/**
* @var ValidatorInterface
*/
protected $validator;

// set its type
protected $attributes = array(
'type' => 'comment'
);public function init()
{

if (null === $this->validator) {

$validator = new StringLength();
$validator->setMax(10);

$validator->setMessage('The comment should not exceed 1000 letters!', StringLength::INVALID);

$this->validator = $validator;
}}/**
* Get a validator if none has been set.
*
* @return ValidatorInterface
*/
public function getValidator()
{
return $this->validator;
}/**
* @param ValidatorInterface $validator
* @return $this
*/
public function setValidator(ValidatorInterface $validator)
{
$this->validator = $validator;
return $this;
}/**
* remove require and validator defaults because we have none
*
* @return array
*/
public function getInputSpecification()
{
//        return array(
//            'name' => $this->getName(),
//            'required' => false,
//            'validators' => array(
//                $this->getValidator(),
//            ),
//            'filters' => array(
//              new FIGradeCommentDynamicBufferFilter()
//            ),
//        );return array(
'name' => $this->getName(),
'required' => false,
'filters' => array(
array('name' => 'Zend\Filter\StringTrim'),
),
'validators' => array(
$this->getValidator(),
),

);
}

// tell it where to find its view helper, so formRow and the like work correctly
public function getViewHelperConfig()
{
return array('type' => '\OnlineFieldEvaluation\View\Helper\FormComment');
}

}

0

Решение

Вы можете создать базовый абстрактный класс фильтра ввода и интерфейс и сделать так, чтобы все ваши фильтры форм расширяли базовый класс, который реализует интерфейс с методами, которые вы ожидаете внутри классов форм, чтобы заставить работу работать правильно.

Сделайте интерфейс с методами:

interface GradeCommentFormFilterInterface()
{
protected function getGradeInput();

protected function getCommentInput();
}

Затем вы перемещаете общий код в ваш базовый класс:

abstract class BaseGradeCommentFormFilter extends InputFilter implements GradeCommentFormFilterInterface
{
protected function getGradeInput()
{
return $this->get(static::GRADE_NAME);
}

protected function getCommentInput()
{
return $this->get(static::GRADE_NAME . 'Comment');
}

public function isValid($context = null)
{
$gradeInput = $this->getGradeInput();
$commentInput = $this->getCommentInput();
$rawValue = $this->getRawValue($gradeInput);

if(is_numeric($rawValue))
{
$gradeValue = intval($rawValue);
}
else
$gradeValue = $rawValue;

if ($gradeValue != 'na' && $gradeValue > 0) {
$commentInput->setRequired(true);
$validatorChain = new Validator\ValidatorChain();
$validatorChain->attach(
new Validator\NotEmpty(),
true
);
$commentInput->setValidatorChain($validatorChain);
}
return parent::isValid($context);
}
}

Теперь вы можете использовать свой абстрактный класс следующим образом:

class CompetencyAdvanceHumanRightsAndJusticeFormFilter extends BaseGradeCommentFormFilter
{
const GRADE_NAME = 'applJusticeFIGrade';

//... other code
}

Я быстро попытался заставить это работать для вашего случая, но это не проверено, и, вероятно, есть способы оптимизировать это, но это дает вам представление о том, что вы можете сделать.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]