Zend Framework 2 Setup default value if invalid input - php

So I created a input filter (see below) but I have to test 24 fields to make sure they are all valid (only 1 listed below to keep this simple). In this case, the input is coming from an e-mail server, not a user, so I need accept the input, and not send an error back. However, I still need to check the data to ensure no one is messing with the headers / fields trying to mess everything up.
So my question is, how can I sent a default value for each input? For example blow, if the mailbox is length 0, something is wrong, so I just want to set the value to be something like 'InvalidMailbox' so I can still store this in the database,
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'mailbox',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StripNewLines'),
array('name' => 'StringToLower'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 200,
),
),
),
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
Calling it...
$mail = new SMail();
$inputFilter = $mail->getInputFilter;
$inputFilter->setData($data);
if ($inputFilter->isValid()) {
//echo "The form is valid\n";
} else {
// Maybe set the default here?
// but with 24 different fields, how can I know which one caused the error?
//echo "The form is not valid\n";
}

Okay, sorry that i didn't get the quest right first time. Going by the Source of the BaseInputFilter, there is a function called getInvalidInput(), so my assumption is, that you can do the following:
$defaultData = array(
'elementName' => 'Default Value'
);
$returnData = array();
if (false === $inputFilter->isValid()) {
$falseInputs = $inputFilter->getInvalidInput();
foreach ($falseInputs as $input) {
$returnData[$input->getName()] = $defaultData[$input->getName()];
}
}
$goodInputs = $inputFilter->getValidInput();
$finalData = array_merge($goodInputs, returnData);
This however is no tested code. I'm not sure if $input->getName() is available. You may need to adjust that part accordingly. I'm quite certain though that this should be able to get you started, hopefully ;)

Related

Overwriting zend form checkbox

I have a problem with the zend form checkbox.
$this->addElement('checkbox', 'languages', array(
'label' => 'Languages',
'class' => 'check_1',
'name' => 'checkset',
'checkedValue' => '1',
'uncheckedValue'=> '0'
));
I made this checkbox and overwritten the checkedValue and uncheckedValue but when I debug it, it has totally different values:
$values = $form_duplicate->getValues();
var_dump($values);
This is the result:
["languages"]=> string(1) "0"
I can't understand where is the problem. I looked up on the zend documentation page and this is how it must be.
I'm not sure I understand your problem, but you can use the setCheckedValue and setUncheckedValue methods to change defaults values like this:
$langages = new Zend_Form_Element_Checkbox('languages', array(
'label' => 'Languages',
'class' => 'check_1',
'name' => 'checkset'
));
$langages->setCheckedValue('value_check');
$langages->setUncheckedValue('value_uncheck');
$this->addElement($langages);
And to recover your values:
if ($this->getRequest()->isPost()) {
$formData = $this->getRequest()->getPost();
// isValid($formData) filled the form with the datas returned
if ($form_duplicate->isValid($formData)) {
// treatment
}
$values = $form_duplicate->getValues();
var_dump($values);
}

Parse date in ZF2

I'm having a problem.
I'm using ZF2, and getting an error here.
$inputFilter->add($factory->createInput(array(
'name' => 'dataInicial',
'required' => true,
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'messages' => array(
\Zend\Validator\NotEmpty::IS_EMPTY => 'A data do feriado deve ser preenchida.'
)
)
),
array(
'name' => 'callback',
'options' => array(
'messages' => array(
\Zend\Validator\Callback::INVALID_CALLBACK => 'Data no formato inválido.'
),
'callback' => function ($value, $context = array()) {
$dataInicial = \DateTime::createFromFormat('d/m/Y', $value);
return $dataInicial->format('d/m/Y');
}
)
)
)
)));
I'm getting this error:
DateTime::__construct(): Failed to parse time string (25/12/2014) at position 0 (2): Unexpected character
When I execute the same code in pure php, without zend, it works ok.
echo DateTime::createFromFormat('d/m/Y', '25/12/2014')->format('d/m/Y');
Maybe someone knows what's causing the error? Sorry for my english
Don't know what kind of database backend and relationship mapping but the issue is related to how the date is being stored I imagine, most likely like: Y/m/d
If you saving and getting this error then it's because you need the date in this format. If you are hydrating you may also need a date strategy to deal with hydration like:
// InputFilter.php
class yourInputFilter()
{
$hydrator->getHydrator()->addStrategy('my_attribute', new MyDateHydrationStrategy());
$this->add( array(
'name' => 'registration_starts',
'type' => 'Zend\Form\Element\DateTime',
'options' => array (
'format'=>'Y/m/d',
)
));
}
// YourForm.php
class YourForm Extends ....
{
$dateTime = new Element\DateTime('youDate');
$dateTime->setLabel('Date')
->setOptions(array(
'format' => 'Y-m-d\TH:iP'
));
}
// Strategy.php
class myDateTimeStrategy implements StrategyInterface
{
public function hydrate($value)
{
if (is_string($value)) {
$value = new DateTime($value);
}
// Could return in a different format, probably can't though because of when you need to edit
// return $value->format("m-d-Y")
return $value;
}
}
You will also need to change js settings if you using a datetime widget picker:
Which will be something like:
$('.datepicker').datepicker('format', 'yyyy/mm/dd');
Depending on which one you using.

remove validation zend form element javascript/jquery

I want to disable the validation on one of the zend form element based on the input on another element on the same form. I need to achieve this using javascript/jquery. Something very common but very surprisingly couldn't find it over the internet.
e.g.
In the controller:
$oFormMassEdit = new Account_Form_Returns_Return();
$this->view->form = $oFormMassEdit;
In Account_Form_Returns_Return's constructor:
$oNoteElement = new Zend_Form_Element_Textarea('option', array(
'required' => true,
));
$this->addElemet($oNoteElement)
$oReasonElement = new Zend_Form_Element_Select('note', array(
'multiOptions' => array (
'return' => 'return',
'defect' => 'Kaput',
'other' => 'Anderer Grund'
),
'required' => true,
));
$this->addElement($oReasonElement);
$this->addDisplayGroup(array('note', 'option'), 'main', array('legend' => 'Retouren'));
$this->addElement('button','send', array(
'type' => 'submit',
'label' => 'Methode speichern',
));
and finally in the view,
<?= $this->form; ?>
Javascript can't (not in a sensible way) switch Zend_Form configuration. What you can do is changing the 'required' param for certain form fields on validation. For example; If you want to allow fieldTwo to be empty if fieldOne has 'desiredValue' as value you can achieve this using the following function in your form:
public function isValid($data) {
if('desiredValue' == $data['fieldOne'])) {
$this->getElement('fieldTwo')->setRequired(false);
}
return parent::isValid($data);
}

CakePHP empty field versus not empty field validations

I have the follow validation rule for a file:
modelFile.php
public $validate = array(
'image' => array(
'maxWidth' => array(
'rule' => array('maxWidth', 2000),
),
'maxHeight' => array(
'rule' => array('maxHeight', 2000),
),
'extension' => array(
'rule' => array('extension', array('gif', 'jpg', 'png', 'jpeg')),
),
'filesize' => array(
'rule' => array('filesize', 5120000),
)
)
);
Have a way to skip validations, if image are empty?
You may have to adjust how you check if the image is empty/not uploaded - I'm not sure if what I have is correct. But the idea is to check and unset the validation rule.
public function beforeValidate($options = array()) {
if (empty($this->data[$this->alias]['image']['name'])) {
unset($this->validate['image']);
}
return true;
}
See below URL
cakePHP optional validation for file upload
Or try it
"I assign $this->data['Catalog']['image'] = $this->data['Catalog']['imageupload']['name'];"
So by the time you save your data array, it looks something like this I assume:
array(
'image' => 'foobar',
'imageupload' => array(
'name' => 'foobar',
'size' => 1234567,
'error' => 0,
...
)
)
Which means, the imageupload validation rule is trying to work on this data:
array(
'name' => 'foobar',
'size' => 1234567,
'error' => 0,
...
)
I.e. the value it's trying to validate is an array of stuff, not just a string. And that is unlikely to pass the specified validation rule. It's also probably never "empty".
Either you create a custom validation rule that can handle this array, or you need to do some more processing in the controller before you try to validate it
Ok, as far as I know there is no such code to set this in your $validate variable. So what you are going to have to do is:
In the beforeValidate of the corresponding model add the following piece of code:
<?php
# Check if the image is set. If not, unbind the validation rule
# Please note the answer of Abid Hussain below. He says the ['image'] will probably
# never be empty. So perhaps you should make use of a different way to check the variable
if (empty($this->data[$this->alias]['image'])){
unset($this->validate['image']);
}
I used http://bakery.cakephp.org/articles/kiger/2008/12/29/simple-way-to-unbind-validation-set-remaining-rules-to-required as my main article. But this function doesn't seem to be a default cake variable. The code above should work.

Zend Framework Form Irrational Behaviour

Let's start this off with a short code snippet I will use to demonstrate my opinion:
$title = new Zend_Form_Element_Text('title', array(
'label' => 'Title',
'required' => false,
'filters' => array(
'StringTrim',
'HtmlEntities'
),
'validators' => array(
array('StringLength', false, array(3, 100))
),
));
This important line is:
'required' => false,
Which means that the input field is not required and you can submit the form without filling it. However, this also means that any filters and validators won't apply to it if you choose to fill in this field.
Common sense tells me that is an irrational behavior. The way I understand the word 'required' in relation with HTML input fields: an input field that is not required should return NULL if it is not filled in but if user decides to fill it both filters and validators should apply to it. That's what makes sense to me. Do you agree with me or is my common sense not so common?
Now more practical question, because this is how Zend_Form behaves, how can I achieve not required fields which would work as I described above (if nothing is typed in by user it returns NULL otherwise filters and validators normally apply).
Not really a complete answer to your question, but since comments don't have syntax formatting; here's a filter you can use to make your field values null if empty.
class My_Filter_NullIfEmpty implements Zend_Filter_Interface
{
public function filter( $value )
{
// maybe you need to expand the conditions here
if( 0 == strlen( $value ) )
{
return null;
}
return $value;
}
}
About the required part:
I'm not sure really. You could try to search the ZF mailinglists on Nabble:
http://www.nabble.com/Zend-Framework-Community-f16154.html
Or subscribe to their mailinglist, and ask them the question. Either through Nabble, or directly via the addresses on framework.zend.com:
http://tinyurl.com/y4f9lz
Edit:
Ok, so now I've done some tests myself, cause what you said all sounded counter intuitive to me. Your example works fine with me. This is what I've used:
<?php
class Form extends Zend_Form
{
public function init()
{
$title = new Zend_Form_Element_Text('title', array(
'label' => 'Title',
'required' => false,
'filters' => array(
'StringTrim',
'HtmlEntities',
'NullIfEmpty' // be sure this one is available
),
'validators' => array(
array('StringLength', false, array(3, 100))
),
));
$this->addElement( $title );
}
}
$form = new Form();
$postValues = array( 'title' => '' ); // or
$postValues = array( 'title' => ' ' ); // or
$postValues = array( 'title' => 'ab' ); // or
$postValues = array( 'title' => ' ab ' ); // or
$postValues = array( 'title' => '<abc>' ); // all work perfectly fine with me
// validate the form (which automatically sets the values in the form object)
if( $form->isValid( $postValues ) )
{
// retrieve the relevant value
var_dump( $form->getValue( 'title' ) );
}
else
{
echo 'form invalid';
}
?>
Actually, what you describe as your expectations are exactly how Zend_Form works. If you mark the element as not required, then the following happens: (a) if no value is passed, it skips validation, but if (b) a value is passed, then it must pass all validators in order to be valid.
BTW, best place to ask ZF questions is on the ZF mailing lists: http://framework.zend.com/archives

Categories