Может ли реализовать динамическую проверку на уровне элемента? я использовал этот Пример для реализации проверки одного элемента в зависимости от значения другого элемента. Но для этого мне нужно будет реализовать это для каждой формы, где я использую этот элемент (комментарий) с этой проверкой. У меня много таких форм. Есть ли способ сделать следующее:
перевести эту логику фильтра / проверки на уровень элемента, используя некоторый атрибут «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');
}
}
Вы можете создать базовый абстрактный класс фильтра ввода и интерфейс и сделать так, чтобы все ваши фильтры форм расширяли базовый класс, который реализует интерфейс с методами, которые вы ожидаете внутри классов форм, чтобы заставить работу работать правильно.
Сделайте интерфейс с методами:
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
}
Я быстро попытался заставить это работать для вашего случая, но это не проверено, и, вероятно, есть способы оптимизировать это, но это дает вам представление о том, что вы можете сделать.
Других решений пока нет …