Вы probaly в конечном итоге с валидатора, как это:
class MyCustomValidator extends ZendAbstractValidator
{
const FIELDS_EMPTY = 'fieldsEmpty';
/**
* Error messages
*
* @var array
*/
protected $abstractMessageTemplates = [
self::FIELDS_EMPTY => "Vale for %field1% is required and can't be empty, if %field2% is not set.",
];
/**
* Variables which can be used in the message templates
*
* @var array
*/
protected $abstractMessageVariables = [
'field1' => 'field1',
'field2' => 'field2',
];
/**
* Value of the field
* @var mixed
*/
protected $value;
/**
* Name of the first field to check, which the validator is bind to
* @var mixed
*/
protected $field1;
/**
* Name of the second field to check
* @var string
*/
protected $field2;
/**
* MyCustomValidator constructor.
*
* @param array|null|\Traversable $options
*
* @throws \Exception
*/
public function __construct($options)
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
if (!array_key_exists('field1', $options) || !array_key_exists('field2', $options)) {
throw new \Exception('Options should include both fields to be defined within the form context');
}
$this->field1 = $options['field1'];
$this->field2 = $options['field2'];
parent::__construct($options);
}
/**
* Returns true if and only if $value meets the validation requirements
* If $value fails validation, then this method returns false, and
* getMessages() will return an array of messages that explain why the
* validation failed.
*
* @param mixed $value
* @param array $context
*
* @return bool
*/
public function isValid($value, $context = [])
{
$this->setValue($value);
if (empty($value) && (array_key_exists($this->field2, $context) || empty($context[$this->field2]))) {
$this->error(self::FIELDS_EMPTY);
return false;
}
return true;
}
}
Так как его использовать:
public function getInputFilterSpecification()
{
return [
'foo' => [
'validators' => [
[
'name' => MyCustomValidator::class,
'options' => [
'field1' => 'foo',
'field2' => 'bar',
]
]
]
],
'bar' => [
'validators' => [
[
'name' => MyCustomValidator::class,
'options' => [
'field1' => 'bar',
'field2' => 'foo',
]
]
]
],
];
}
для тех, кто не знает, как зарегистрировать MyCustomValidator - в вашем module.config.php или использовать public function getValidatorConfig()
в вашем module.php. Не использовать оба, это один или другой:
Как зарегистрироваться в вашей module.config.php
'validators' => array(
'factories' => array(
MyCustomValidator::class => MyCustomValidatorFactory::class,
),
),
Как зарегистрироваться в вашем module.php:
/**
* Expected to return \Zend\ServiceManager\Config object or array to
* seed such an object.
* @return array|\Zend\ServiceManager\Config
*/
public function getValidatorConfig()
{
return [
'aliases' => [
'myCustomValidator' => MyCustomValidator::class,
'MyCustomValidator' => MyCustomValidator::class,
'mycustomvalidator' => MyCustomValidator::class,
],
'factories' => [
MyCustomValidator::class => MyCustomValidatorFactory::class,
],
];
}
завод класс:
class MyCustomValidatorFactory implements FactoryInterface, MutableCreationOptionsInterface
{
/**
* Options for the InputFilter
*
* @var array
*/
protected $options;
/**
* Create InputFilter
*
* @param ServiceLocatorInterface $serviceLocator
*
* @return BlockChangeOnSerialsValidator
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
return new MyCustomValidator($this->options);
}
/**
* Set creation options
*
* @param array $options
*
* @return void
*/
public function setCreationOptions(array $options)
{
$this->setOptions($options);
}
/**
* Set options
*
* @param array $options
*/
public function setOptions(array $options)
{
$this->options = $options;
}
}
Обратите внимание, что я держал метод валидатор isValid()
довольно прост, как я не уверен, что это было с преодолевая ваше дело, но это поможет вам двигаться в правильном направлении. Но улучшение, которое может быть сделано, - это повторно использовать средство проверки NotEmpty, чтобы проверить, пустое ли поле или нет.
Обратите внимание: Контекст witin формы isValid($value, $context = null)
является формойОбъявление при звонке $form->setData($this->getRequest()->getPost())
.
Спасибо за ваш ответ, но он не работает в случае с «условно обязательными» полями, которые я описал в вопросе. Пожалуйста, прочитайте вопрос. – automatix
Ahh okay. Я вижу, что мне было немного поскорее с моим завершением, потому что вы выделили «Как настроить сообщение об ошибке». Попробуем обновить свой ответ, так как это, скорее всего, придет к настраиваемому валидатору. – Kwido
@automatix Помог ли мой обновленный ответ? Поскольку вопрос по-прежнему остается без ответа, вы нашли решение уже для него? – Kwido