Validate default values - zend-framework

I have a form which consists of selects/dropdowns. I have set their default values to be -1. When the form is submitted, I want to validate that the submitted value is not equal to the default value. I tried setRequired(true), but as far as I know, that is just a convenient way of adding a notEmpty validator, which is not really what I want.
Here is a part of my form:
$select = new Zend_Form_Element_Select('myselect');
$select->setMultiOptions(array(
'-1' => 'Gender',
'0' => 'Female',
'1' => 'Male'
))
->addValidator(new Zend_Validate_Int(), false);
$this->setDefaults(array('myselect' => -1));
And here is my controller:
if ($this->getRequest()->isPost()) {
$form = new My_Form_Contact();
if ($form->isValidPartial(array('myselect' => $this->getRequest()->getPost('myselect')))) {
// "myselect" is valid
}
I need to use the isValidPartial method because I need to use different logic depending on which elements have a value that is different from their default value. I guess what I need is a notEqual validator, but I couldn't find one. I know that it is possible to make my own validators, but I wanted to ask if there is an easier way first. I also looked at Zend_Validate_Identical, but I don't think I can make use of it in this case.
To sum up: I only want my select to be validated successfully if the submitted value is not equal to the default value.

The simplest solution is to use an empty string as the default:
$select->setMultiOptions(array(
'' => 'Gender',
'0' => 'Female',
'1' => 'Male'
))
->addValidator(new Zend_Validate_Int(), false)
->addValidator(new Zend_Validate_NotEmpty(), false);
$this->setDefaults(array('myselect' => ''));
but I'm guessing you already thought of that, and discounted it from some reason.
So, the next easiest is to use GreaterThan():
$select->setMultiOptions(array(
'-1' => 'Gender',
'0' => 'Female',
'1' => 'Male'
))
->addValidator(new Zend_Validate_Int(), false)
->addValidator(new Zend_Validate_GreaterThan(-1), false);
$this->setDefaults(array('myselect' => '-1'));
I hope that is what you are looking for.

Related

zf2 doctrine form int required not working

$inputFilter->add(array(
'name' => 'seatingCapacity',
'required' => TRUE,
'filters' => array(
array('name' => 'Int'),
),
));
In my Doctrine Entity, I have a getInputFilter method which I use for form validation. The above is code snippet for one of the input elements. My problem is the required => true is not working even if I submit an empty form.
After researching I found out, that the Int filter converts the empty input to 0 and submits it and that is why the required validator is not working. I just need reasons why it may not be working.
For reference where I searched
Zend Framework 2 - Integer Form Validation
where he suggests to use Between validator
$inputFilter->add($factory->createInput(array(
'name' => 'zip',
'required' => true,
'filters' => array(
array('name' => 'Int'),
),
'validators' => array(
array(
'name' => 'Between',
'options' => array(
'min' => 1,
'max' => 1000,
)
)
)
)
));
I want to know why I should use Between and why required is failing.
You should only use the Between validator to validate if the given value is Between a min and max value. It has nothing to do with solving your empty value to 0 issue.
You should ask yourself 2 questions:
Is 0 a valid value?
Do I want to automatically cast null empty string ('') and other empty values to this 0 or not?
If you actually want to prevent that the Int filter sets an empty value to 0, maybe then you should not use this filter at all then?
You can instead add an IsInt validator to check if the given value is an integer. Your required => true setting will work as expected and validation will fail on any other (not integer) input so also on null, empty strings etc.
Thank you for your time, energy & effort.
Actually I solved the problem.
I had copy-pasted the code, which I should have been careful while doing so.
What I found out is there is no such filter named 'Int' and actually it's 'Digits'
$inputFilter->add(array(
'name' => 'seatingCapacity',
'required' => TRUE,
'filters' => array(
array('name' => 'Int'),
),
));
shows me error because the filter name should have been 'Digits'.
Only doing so solved my problem and works as per my requirement.
$inputFilter->add(array(
'name' => 'seatingCapacity',
'required' => TRUE,
'filters' => array(
array('name' => 'Digits'),
),
));
This is the right way to do and I would advice you to be careful while referring code from your sources because it's an illogical mistake I did.
Happy coding

Duplicate Validation on Combined Fields in zend form

Hi there I have a table in which combination of three fields is unique. I want to put the check of duplication on this combination. Table looks like
I know how to validate single field, But how to validate the combination is not know. To validate one field I use the following function
public function isValid($data) {
// Options for name field validation
$options = array(
'adapter' => Zend_Db_Table::getDefaultAdapter(),
'table' => 'currencies',
'field' => 'name',
'message'=> ('this currency name already exists in our DB'),
);
// Exclude if a id is given (edit action)
if (isset($data['id'])) {
$options['exclude'] = array('field' => 'id', 'value' => $data['id']);
}
// Validate that name is not already in use
$this->getElement('name')
->addValidator('Db_NoRecordExists', false, $options
);
return parent::isValid($data);
}
Will any body guide me how can I validate duplication on combined fields?
There is no ready to use validator for this, as far as I know. You have either to write your own, or do a check with SQL-query with three conditions (one for each field).
you have to Apply a validation on name element of zend form.
Here is code for add validation on name field.
$name->addValidator(
'Db_NoRecordExists',
true,
array(
'table' => 'currencies',
'field' => 'name',
'messages' => array( "recordFound" => "This Currency Name already exists in our DB") ,
)
);
And you must set required true.

zend form float and integer validation

I am using zend form. I want to validate a field and want to allow only flat and integer values in the field. It means user can either enter any floating value like 2.0 or 3.56, etc OR 4 or 7, etc. But I dont want to receive alpha numeric or alphabet input.
I have used digit validator but it only allows digits not floating number.
Can any body tell me how to put both validations together?
My code is as follows
$parent_affiliate_commission = new Zend_Form_Element_Text('parent_affiliate_commission');
$parent_affiliate_commission->setRequired(true)
->addFilter('StringTrim')
->addFilter('StripTags')
->addValidator('Digits')
->setAttrib('class', 'small')
->addValidator('StringLength', false, array(2, 100))
->setDecorators(array('ViewHelper', 'errors'))
It would be really easy to create and use a custom validator. You could validate simply by using PHP is_int and is_float functions and still do in the 'Zend way'.
By using the callback method I have validated the value in numeric.Because it will not allow the characters.
$inputFilter->add(
$factory->createInput(
array(
'name' => 'proximity',
'required' => true,
'validators' => array(
array(
'name' => 'Callback',
'options' => array(
'messages' => array(
\Zend\Validator\Callback::INVALID_VALUE => 'The proximity value should be numbers'
),
'callback' => function (
$value,
$context = array())
{
$isValid = is_numeric(
$value);
return $isValid;
}
)
)
)
)));

Zend_Validate_Db_RecordExists against 2 fields

I usualy use Zend_Validate_Db_RecordExists to update or insert a record. This works fine with one field to check against. How to do it if you have two fields to check?
$validator = new Zend_Validate_Db_RecordExists(
array(
'table' => $this->_name,
'field' => 'id_sector,day_of_week'
)
);
if ($validator->isValid($fields_values['id_sector'],$fields_values['day_of_week'])){
//true
}
I tried it with an array and comma separated list, nothing works... Any help is welcome.
Regards
Andrea
To do this you would have to extend the Zend_Validate_Db_RecordExists class.
It doesn't currently know how to check for the existence of more than one field.
You could just use two different validator instances to check the two fields separately. This is the only work around that I can see right now besides extending it.
If you choose to extend it then you'll have to find some way of passing in all the fields to the constructor ( array seems like a good choice ), and then you'll have to dig into the method that creates the sql query. In this method you'll have to loop over the array of fields that were passed in to the constructor.
You should look into using the exclude parameter. Something like this should do what you want:
$validator = new Zend_Validate_Db_RecordExists(
array(
'table' => $this->_name,
'field' => 'id_sector',
'exclude' => array(
'field' => 'day_of_week',
'value' => $fields_values['day_of_week']
)
);
The exclude field will effectively add to the automatically generated WHERE part to create something equivalent to this:
WHERE `id_sector` = $fields_values['id_sector'] AND `day_of_week` = $fields_values['day_of_week']
Its kind of a hack in that we're using it for the opposite of what it was intended, but its working for me similar to this (I'm using it with Db_NoRecordExists).
Source: Zend_Validate_Db_NoRecordExists example
Sorry for the late reply.
The best option that worked for me is this:
// create an instance of the Zend_Validate_Db_RecordExists class
// pass in the database table name and the first field (as usual)...
$validator = new Zend_Validate_Db_RecordExists(array(
'table' => 'tablename',
'field' => 'first_field'
));
// reset the where clause used by Zend_Validate_Db_RecordExists
$validator->getSelect()->reset('where');
// set again the first field and the second field.
// :value is a named parameter that will be substituted
// by the value passed to the isValid method
$validator->getSelect()->where('first_field = ?', $first_field);
$validator->getSelect()->where('second_field = :value', $second_field);
// add your new record exist based on 2 fields validator to your element.
$element = new Zend_Form_Element_Text('element');
$element->addValidator($validator);
// add the validated element to the form.
$form->addElement($element);
I hope that will help someone :)
Although, I would strongly recommend a neater solution which would be to extend the Zend_Validate_Db_RecordExists class with the above code.
Enjoy!!
Rosario
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
'validators' => array('EmailAddress', $obj= new Zend_Validate_Db_NoRecordExists(array('adapter'=>$dbAdapter,
'field'=>'email',
'table'=>'user',
'exclude'=>array('field'=>'email','value'=>$this->_options['email'], 'field'=>'is_deleted', 'value'=>'1')
))),
For those using Zend 2, If you want to check if user with given id and email exists in table users, It is possible this way.
First, you create the select object that will be use as parameter for the Zend\Validator\Db\RecordExists object
$select = new Zend\Db\Sql\Select();
$select->from('users')
->where->equalTo('id', $user_id)
->where->equalTo('email', $email);
Now, create RecordExists object and check the existence this way
$validator = new Zend\Validator\Db\RecordExists($select);
$validator->setAdapter($dbAdapter);
if ($validator->isValid($username)) {
echo 'This user is valid';
} else {
//get and display errors
$messages = $validator->getMessages();
foreach ($messages as $message) {
echo "$message\n";
}
}
This sample is from ZF2 official doc
You can use the 'exclude' in this parameter pass the second clause that you want to filter through.
$clause = 'table.field2 = value';
$validator = new Zend_Validate_Db_RecordExists(
array(
'table' => 'table',
'field' => 'field1',
'exclude' => $clause
)
);
if ($validator->isValid('value') {
true;
}
I am using zend framework v.3 and validation via InputFilter(), it uses same validation rules as zend framework 2.
In my case I need to check, if location exists in db (by 'id' field) and has needed company's id ('company_id' field).
I implemented it in next way:
$clause = new Operator('company_id', Operator::OP_EQ, $companyId);
$inputFilter->add([
'name' => 'location_id',
'required' => false,
'filters' => [
['name' => 'StringTrim'],
['name' => 'ToInt'],
],
'validators' => [
[
'name' => 'Int',
],
[
'name' => 'dbRecordExists',
'options' => [
'adapter' => $dbAdapterCore,
'table' => 'locations',
'field' => 'id',
'exclude' => $clause,
'messages' => [
'noRecordFound' => "Location does not exist.",
],
]
],
],
]);
In this case validation will pass, only if 'locations' table has item with columns id == $value and company_id == $companyId, like next:
select * from location where id = ? AND company_id = ?

How to set the default checked value of a Zend_Form Radio Element?

I have a radio element with two options. I want to set one as the default value in case the user forgets to check it. How can I do this?
Solution:
$this->addElement('radio', 'choose', array(
'required' => true,
'multiOptions' => array(
'yes' => 'heck yes',
'no' => 'please no'
),
'value' => 'yes' //key of multiOption
));
use setValue with key. For example:
$enablestate=new Zend_Form_Element_Radio('enablestate');
$enablestate->addMultiOptions(array('enabled'=>'Enabled','unenabled'=>'Unenabled'));
$enablestate->setSeparator('')->setValue('enabled');
this code should do it
$radio = new Zend_Form_Element_Radio('radio');
$radio->addMultiOption("option1", "option1")->setAttrib("checked", "checked");
$radio->addMultiOption("option2", "option2");
$this->addElement($radio);
for further readings you can refer to:
ZendFramework manual
http://www.w3schools.com/html/html_forms.asp
This is how I do when I use element objects
$myRadio = new Element\Radio('myradio');
$myRadio->setLabel("Are you mad?");
$myRadio->setValueOptions(array('0'=>'Yes', '1' =>'No', '2'=>'Maybe'));
$myRadio->setValue('2'); //set it 0 if you sure you know it
$this->add($myRadio);