In my form I have a field foo
, that should be unique in the database table. So I added a Zend\Validator\Db\NoRecordExists
to its validators list:
namespace Bar\Form\Fieldset;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\Db\Adapter\AdapterInterface;
class BuzFieldset extends Fieldset implements InputFilterProviderInterface
{
protected $dbAdapter;
public function __construct($name = null, $options = []) {...}
public function setDbAdapter(AdapterInterface $dbAdapter) {...}
public function init()
{
$this->add([
'name' => 'id',
'type' => 'hidden'
]);
$this->add(
[
'name' => 'foo',
'type' => 'text',
'options' => [...],
'attributes' => [
'required' => 'required',
'class' => 'form-control'
]
]);
...
}
public function getInputFilterSpecification()
{
return [
'foo' => [
'required' => true,
'validators' => [
[
'name' => 'Regex',
'options' => [
'pattern' => '/.../',
'message' => _(...)
]
],
[
'name' => 'Zend\Validator\Db\NoRecordExists',
'options' => [
'table' => 'buz',
'field' => 'foo',
'adapter' => $this->dbAdapter
]
]
]
],
...
];
}
}
Now I want to use the same form for updating entries and of course cannot get the form validated. So I need to make the NoRecordExists
validation for this field dependent on the field id
. If id
is set (that means, it's updating, not a creating), all validators (e.g. here Regex
) should be applied, but this one not. How to do that?
You can have a look at the Callback validator. This validator will give you access to the form context allowing you to get the values of other fields. Use the NoRecordExists
validator inside the Callback
validator to make it dependend. Something like this. I didn't test this, but you'll get the idea.
'foo' => [
'required' => true,
'validators' => [
[
'name' => 'Callback',
'options' => [
'callback' => function($value, $context = []) {
if (empty($context['id'])) {
return $this->noRecordExistsValidator->isValid($value);
}
return true;
},
],
]
]
]
You'll need to inject the NoRecordExistsValidator
as a dependency to this form class, or better yet create a seperate InputFilter
and corresponding factories which fully setup the InputFilter
and inject that instance into the Fieldset
object.