Zend Framework 2 - Removed form element causes validation to fail
Ok, finally I found a solution! You can define a ValidationGroup
which allows you to set the attributes you'd like to validate. The others are not validated:
$form->setValidationGroup('name', 'email', 'subject', 'message');
$form->setData($data);
if ($form->isValid()) {
...
Strange form validation behavior in Zend Framework 2
Many people loathed the forms in ZF1.x for the decorators but I loved it nonetheless. What is the worst part for me with ZF2 is that you can basically throw out all your knowledge because like so many things in ZF2 it has completely changed.
There is the new (HTML5) email element but it comes with a hard coded required constraint. Similar stuff happens with select elements. In ZF1 you had the setRequired()
method on the element but it is now moved back into what are "inputs" in the form. In other word you have to get the inputs first.
$form->prepare(); // this is another new thing and necessary
$input = $form->getInputFilter();
$e_filter = $input->get('email');
$e_filter->setRequired(false);
$g_filter = $input->get('gender');
$g_filter->setRequired(false);
Now your form should accept empty submissions.
UPDATE: As for the postback problem.
It all depends on the data you set with setData()
. This could be either the POST data or on a redirect data from a session. If you submit without a selection the POST data you get should not have any "gender" data and so should the data you set into the form.
UPDATE 2
It looks like the root problem is that an empty gender value is submitted and POST values are always strings, hence an empty value is of type string with length 0. Looking into Form\View\Helper\FormSelect
and the rendering of the option you will find a in_array($value, $selectedOptions)
function handling the selected attribute. Unfortunately they don't set the strict flag and without that a 0
(zero) value matches an empty string.
$post = array('gender' => '');
$bool = in_array(0, $post); // this is true
$bool = in_array(0, $post, true); // but this is false
So, either filter/remove this empty value from the POST or change the empty string to NULL before you'll add it to setData() then it will be droped as a selected option. Additionally if you can of course add/change the strict option in the Zend class (which I wouldn't do).
How to disable/remove a validator of a element depending on the value of another element?
I've got around the problem by overwriting the isValid()
method in the form:
class CreateProduct extends Form
{
public function init()
{
/* ... */
}
public function isValid()
{
if (!$this->get('product')->get('isSale')->isChecked()) {
$this->getInputFilter()->get('product')->remove('salePrice');
$this->get('product')->get('salePrice')->setValue(null);
}
return parent::isValid();
}
}
It feels so hacky though!
Zend framework 2 optional form validation
To set the validator in an input filter you would do something like this in a validator class:
$inputFilter->add($factory->createInput(array(
'name' => 'foo_bar_input',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim')
),
// add your validators here
'validators' => array(
// check to see if an input is empty
array(
'name' => 'Zend\Validator\NotEmpty',
'options' => array(),
)
)
)));
Then to use the filter with your form, do something like:
$validate = $this->getServiceLocator()->get('your_validator_class');
$form->setInputFilter($validate->getInputFilter());
The just check to see if your form is valid:
if ($form->isValid())
{
// do stuff
}
Here is ZF2's documentation on the NotEmpty validator:
http://framework.zend.com/manual/2.0/en/modules/zend.validator.set.html#notempty
Set Zend Framework 2 form element to disabled
Simply use disabled attribute instead of setting element options:
$dropDownForCheckBox->setAttribute('disabled', 'disabled');
Empty values passed to Zend framework 2 validators
Following works for ZF2 version 2.1.1:
The problem (if I got it correctly) is that in following example, for empty values of 'fieldName'
, no validation is triggered. This can be quite annoying, though in
$input = new \Zend\InputFilter\Input('fieldName');
$input
->setAllowEmpty(true)
->setRequired(false)
->getValidatorChain()
->attach(new \Zend\Validator\Callback(function ($value) {
echo 'called validator!';
return true; // valid
}));
$inputFilter = new \Zend\InputFilter\InputFilter();
$inputFilter->add($input);
$inputFilter->setData(array('fieldName' => 'value'));
var_dump($inputFilter->isValid()); // true, echoes 'called validator!'
$inputFilter->setData(array('fieldName' => ''));
var_dump($inputFilter->isValid()); // true, no output
$inputFilter->setData(array());
var_dump($inputFilter->isValid()); // true, no output
This is quite annoying when you have particular cases, like checking an URL assigned to a page in your CMS and avoiding collisions (empty URL is still an URL!).
There's a way of handling this for empty strings, which is to basically attach the NotEmpty
validator on your own, and avoiding calls to setRequired
and setAllowEmpty
. This will basically tell Zend\InputFilter\Input#injectNotEmptyValidator
not to utomatically attach a NotEmpty
validator on its own:
$input = new \Zend\InputFilter\Input('fieldName');
$input
->getValidatorChain()
->attach(new \Zend\Validator\NotEmpty(\Zend\Validator\NotEmpty::NULL))
->attach(new \Zend\Validator\Callback(function ($value) {
echo 'called validator!';
return true; // valid
}));
$inputFilter = new \Zend\InputFilter\InputFilter();
$inputFilter->add($input);
$inputFilter->setData(array('fieldName' => 'value'));
var_dump($inputFilter->isValid()); // true, echoes 'called validator!'
$inputFilter->setData(array('fieldName' => ''));
var_dump($inputFilter->isValid()); // true, echoes 'called validator!'
$inputFilter->setData(array());
var_dump($inputFilter->isValid()); // false (null was passed to the validator)
If you also want to check against null
, you will need to extend Zend\InputFilter\Input
as following:
class MyInput extends \Zend\InputFilter\Input
{
// disabling auto-injection of the `NotEmpty` validator
protected function injectNotEmptyValidator() {}
}
Related Topics
PHP String Concatenation - "$A $B" VS $A . " " . $B - Performance
How to Subtract 24 Hour from Date Time Object in PHP
How to Access MySQLi Connection in Another Class on Another Page
Http Referer Not Always Being Passed
How to Detect If a User Uploaded a File Larger Than Post_Max_Size
Fatal Error: Call to Undefined Function MySQL_Connect() in C:\Apache\Htdocs\Test.PHP on Line 2
Remove Everything Except Letters from PHP String
Unable to Scrape Content from a Website
What Is Laravel Render() Method For
What's the Difference Between If(!$Variable) and If(Isset($Variable))
Does the Use Keyword in PHP Closures Pass by Reference
Replace the Last Comma in a String Using Regular Expression
How to Display Images from a Folder Using PHP - PHP