How to disable filter of a field in Zend Framework 2 in the controller? - forms

Form to add/edit user I get from service manager with already installed filter, which is the test password. But this password is not needed when the user is edited. Can I somehow disabled password field validation in the controller?
In the getServiceConfig function of the module:
// ....
'UserCRUDFilter' => function($sm)
{
return new \Users\Form\UserCRUDFilter();
},
'UserCRUDForm' => function($sm, $param, $param1)
{
$form = new \Users\Form\UserCRUDForm();
$form->setInputFilter($sm->get('UserCRUDFilter'));
return $form;
},
// ....
In the controller I first of all getting a form object from service manager:
$form = $this->getServiceLocator()->get('UserCRUDForm');
Then disable user password validation and requirements, when user is edited and password not specified:
if ($user_id > 0 && $this->request->getPost('password') == '') {
$form->.... // Someway gained access to the filter class and change the password field validation
}
And after this i make a validation:
$form->isValid();

I found it!
// If user is editted - clear password requirement
if ($user_id > 0) {
$form->getInputFilter()->get('password')->setRequired(false);
$form->getInputFilter()->get('confirm_password')->setRequired(false);
}
This lines is disables requirement of input form fields :)

if you like to set all validators by yourself, call inside your form class
$this->setUseInputFilterDefaults(false);
to disable auto element validations/filter added from zend.
if you like to remove filter from elements call in your controller after your form object this
$form->getInputFilter()->remove('InputFilterName');

$form->get('password')->removeValidator('VALIDATOR_NAME'); should do the trick.
Note that you may have to iterate trough the Validatorchain when using Fieldsets.

$inputFilter->add(array(
'name' => 'password',
'required' => true,
'allow_empty' => true,
));
And on ModeleTable: saveModule:
public function saveAlbum(Album $album)
{
$data = array(
'name' => $album->name,
);
if (isset($album->password)){
$data['password'] = $album->password;
}

Related

CakePHP - Model validation does not work

again alot of similar questions out there but none of them really help me.
HTML5 form validation seems to be triggering with messages "Please fill in this field" instead of the model validation messages which should be "Please enter the model"
I have a form to add Computers to the database.
Here is my form:
echo $this->Form->create('Computer');
echo $this->Form->input('Computer.model', array('label' => 'Model'));
echo $this->Form->input('Computer.memory', array('label' => 'memory'));
echo $this->Form->input('Computer.hdd', array('label' => 'hdd'));
echo $this->Form->input('Computer.price', array('label' => 'price'));
echo $this->Form->end('Save Computer');
Here is the full controller code with index and add actions
<?php
class ComputersController extends AppController {
public $helpers = array('Html', 'Form', 'Session');
public $components = array('Session');
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('add');
}
public function index() {
$this->set('computers', $this->Computer->find('all'));
}
public function add() {
if ($this->request->is('post')) {
if (!empty($this->request->data)) {
$this->Computer->save($this->request->data);
$this->Session->setFlash(__('Your Computer has been saved, or so it seems.....'));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('Not sure why we got here 1.'));
} else {
$this->Session->setFlash(__('By right, this should be the index page'));
}
}
}
?>
Here's the model
<?php
class Computer extends AppModel {
public $validate = array(
'model' => array(
'Please enter model name'=> array(
'rule'=>'notEmpty',
'message'=>'Please enter model'
)
)
);
}
?>
I read from other forms that triggering the model save function, which I do, will automatically trigger the model validation. How can i get the model validation to work?
Thanks
Kevin
As you were saying, if you have the notEmpty validation in the model, CakePHP adds required="required" on the input attributes. This is handled by the browser, so you see the default Please enter this field message when you try to submit an empty value. An advantage is that if you are using the browser in a different language, the message will be displayed in that language.
If you want to change that message, you can try a solution like the ones from this question. (this is probably not what you want)
If you want to remove that client-side message, you can disable it using novalidate
echo $this->Form->create('Computer', array('novalidate' => 'novalidate'));
This way, the HTML5 required property will be ignored, and you will get the message from the model.
I am not sure if there is a way to tell Cake to use the server-side value on the client.
$this->{Model}->save() returns false if the validation fails, but in your case you're redirecting with a flash message after save function. so first check the form is saving perfectly or not, if perfectly saving then redirect to listing page other wise render your view file with a flash message where you can view the validation messages.
if ($this->Computer->save($this->request->data)) {
$this->Session->setFlash(__('Your Computer has been saved, or so it seems.....'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('Unable to save form'));
}
Note: To disable html validation just do
$this->Form->inputDefaults(array(
'required' => false
));
in your view file
Hope this helps you.
Set 'novalidate' => true in options for FormHelper::create()
echo $this->Form->create('Computer', array('novalidate' => true));
For more information, go to http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html

Drupal 6 - ignore required form field

I need to ignore the validation of two form field while creating a user in Drupal 6 but I don't know at all how to do :
$userinfo = array(
'name' => $login,
'init' => $mail,
'mail' => $mail,
'pass' => $password,
'status' => 1,
'lastname' => "", //how to ignore those required fields that invalidate the form
'surname' => "" //how to ignore those required fields that invalidate the form
);
// register a new user
$form_state = array();
$form_state['values'] = $userinfo;
drupal_execute('user_register', $form_state);
$errors = form_get_errors(); // getting 2 required field errors
Note that I can't supress the "required" property as it is used elsewhere in a more "complex" form.
Thanks
I haven't got a D6 site handy to test this on but I think it'll work...
Since drupal_execute() pushes you through the whole form build process you can take advantage of hook_form_alter() to remove the required status, but only in a context you pass along in the $form_state. For example
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'user_register' && !empty($form_state['custom_execution'])) {
$form['lastname']['#required'] = FALSE;
// etc...
}
}
...
$form_state = array();
$form_state['values'] = $userinfo;
$form_state['custom_execution'] = TRUE;
drupal_execute('user_register', $form_state);
Can't you use hook_form_alter to supress the "required" property, only when the from is not used in its "complex" form?
For instance, if you know what paths the "complex" form is used, you can check if that paths is being served with arg.
Better checks may be available...

How to use form validation in Drupal 7

I am trying to edit the checkout form in Drupal Commerce, to require a user to enter their email address twice. When they submit their form, Drupal should check to see if the emails match, and call form_set_error() if they don't. For now, I am just trying to attach a custom validation function to the form, which I can't get to work. (My module is called checkout_confirm_email. This module is only for our own use, so I didn't put much effort into the name).
function checkout_confirm_email_form_alter(&$form, &$form_state, $form_id) {
if($form_id == 'commerce_checkout_form_checkout') {
$form['#validate'][] = 'checkout_confirm_email_form_validate';
dprint_r($form['#validate']);
dsm("I printed");
}
}
function checkout_confirm_email_form_validate($form, &$form_state) {
dsm("Never prints...");
}
The dprint_r statment outputs Array ([0] => checkout_confirm_email_form_validate). So the function is part of the form array, but the dsm statement in the validation function never prints.
I've actually been stuck for a while. I've looked up examples, and I can't see what I'm doing wrong. Anyone?
You need to attach the #validate property to the form submit button like this:
$form['submit']['#validate'][] = 'checkout_confirm_email_form_validate'
And it'll work then it's not necessary that my example is identical match to your form tree you should search for the submit button array and apply this example to it
Instead of form_set_error() I would use form_error($form, t('Error message.'));
function checkout_confirm_email_form_alter(&$form, &$form_state, $form_id) {
if($form_id == 'commerce_checkout_form_checkout') {
$form['#validate'][] = 'checkout_confirm_email_form_validate';
dpm($form['#validate']);
dsm("I printed");
}
}
function checkout_confirm_email_form_validate(&$form, &$form_state) {
// Not sure the exact email field
if(empty($form['submitted']['mail']['#value'])){
dsm("Should see me now and return to the form for re-submission.");
form_error($form, t('Username or email address already in use.'));
}
}
You could use any validate function here
https://api.drupal.org/api/drupal/includes!form.inc/7
The listed validations would be
date_validate - Validates the date type to prevent invalid dates
(e.g., February 30, 2006).
element_validate_integer -Form element validation handler for
integer elements.
element_validate_integer_positive - Form element validation handler
for integer elements that must be positive
element_validate_number - Form element validation handler for
number elements.
password_confirm_validate - Validates a password_confirm element.
Ex of usage
$form['my_number_field'] = array(
'#type' => 'textfield',
'#title' => t('Number'),
'#default_value' => 0,
'#size' => 20,
'#maxlength' => 128,
'#required' => TRUE,
'#element_validate' => array('element_validate_number')
);
You can use _form_validate().
function my_form_form_validate($form, &$form_state) {
if ((valid_email_address($form_state['values']['field_candid_email'])) === FALSE) {
form_set_error('field_candid_email', t('The email address is not valid.'));
}
if (!(is_numeric($form_state ['values']['field_candid_montant']))) {
form_set_error('field_candid_montant', t('The field value must be numeric.'));
}
}
I changed this line:
$form['submit']['#validate'][] = 'checkout_confirm_email_form_validate'
to this:
$form['actions']['submit']['#validate'][] = 'checkout_confirm_email_form_validate';
And it's works !
Use the following code:
$form['submit']['#validate'][] = 'checkout_confirm_email_form_validate'

How to add validators on the fly in Symfony2?

I've a password form field (not mapped to User password) to be used in a change password form, along with two other (mapped) fields, first and last.
I've to add validators on the fly: if value for password is blank then no validation should occur. Otherwise a new MinLength and MaxLength validators should be added.
Here is what i've done so far: create the repeated password field, add a CallbackValidator and return if $form->getData() is null.
Then, how can i add validators for minimum and maximum length to $field?
$builder = $this->createFormBuilder($user);
$field = $builder->create('new_password', 'repeated', array(
'type' => 'password',
'first_name' => 'Password',
'second_name' => 'Confirm password',
'required' => false,
'property_path' => false // Not mapped to the entity password
));
// Add a callback validator the the password field
$field->addValidator(new Form\CallbackValidator(function($form) {
$data = $form->getData();
if(is_null($data)) return; // Field is blank
// Here password is provided and match confirm, check min = 3 max = 10
}));
// Add fields to the form
$form = $builder
->add('first', 'text', array('required' => false)) // Mapped
->add('last', 'text', array('required' => false)) // Mapped
->add($field) // Not mapped
->getForm();
Oh well, found a solution myself after a few experiments.
I'm going to leave this question unanswered for a couple of days as one can post a better solution, that would be really really welcome :)
In particular, i found the new FormError part redundat, don't know if there is a better way to add the error to the form. And honestly, don't know why new Form\CallbackValidator works while new CallbackValidator won't.
So, don't forget to add use statements like these:
use Symfony\Component\Form as Form, // Mendatory
Symfony\Component\Form\FormInterface,
Symfony\Component\Validator\Constraints\MinLength,
Symfony\Component\Validator\Constraints\MinLengthValidator;
And the callback is:
$validation = function(FormInterface $form) {
// If $data is null then the field was blank, do nothing more
if(is_null($data = $form->getData())) return;
// Create a new MinLengthValidator
$validator = new MinLengthValidator();
// If $data is invalid against the MinLength constraint add the error
if(!$validator->isValid($data, new MinLength(array('limit' => 3)))) :
$template = $validator->getMessageTemplate(); // Default error msg
$parameters = $validator->getMessageParameters(); // Default parameters
// Add the error to the form (to the field "password")
$form->addError(new Form\FormError($template, $parameters));
endif;
};
Well, and this is the part i can't understand (why i'm forced to prefix with Form), but it's fine:
$builder->get('password')->addValidator(new Form\CallbackValidator($validation));
addValidator was deprecated and completly removed since Symfony 2.3.
You can do that by listening to the POST_SUBMIT event
$builder->addEventListener(FormEvents::POST_SUBMIT, function ($event) {
$data = $event->getData();
$form = $event->getForm();
if (null === $data) {
return;
}
if ("Your logic here") {
$form->get('new_password')->addError(new FormError());
}
});

PHPunit Dispatch controller action with POST and form

I have a PHPunit test like this:
public function testUsersCanRegisterWhenUsingValidData()
{
$this->request->setMethod('POST')
->setPost(array(
'username' => 'user123',
'zip_code' => '43215',
'email' => 'me1#something.com',
'password' => 'secret',
'confirm_pswd' => 'secret',
));
$this->dispatch('/account/register');
$this->assertRedirectTo('/account/login');
}
and a User controller action called register like this :
public function registerAction()
{
// Instantiate the registration form model
$form = new Application_Model_FormRegister();
// Has the form been submitted?
if ($this->getRequest()->isPost()) {
// If the form data is valid, process it
if ($form->isValid($this->_request->getPost())) {
// Does an account associated with this username already exist?
$account = $this->em->getRepository('Entities\Account')
->findOneByUsernameOrEmail($form->getValue('username'), $form->getValue('email'));
if (! $account)
{ // do something
.............
..............
} else {
$this->view->errors = array(
array("The desired username {$form->getValue('username')} has already been taken, or
the provided e-mail address is already associated with a registered user.")
);
}
} else {
$this->view->errors = $form->getErrors();
}
}
$this->view->form = $form;
}
I get an error in this line :
$account = $this->em->getRepository('Entities\Account')
->findOneByUsernameOrEmail($form->getValue('username'), $form->getValue('email'));
It's caused by $form->getValue('username') being NULL because the form has not actually been submitted, instead PHPunit has dispatched the action and set up the POST variables.
How can I get this working?
Sorry everyone. I had commented out this line to try and study my problem:
// If the form data is valid, process it
if ($form->isValid($this->_request->getPost())) {
and it turns out that my input test input was not valid and you can't use $form->getValue to get the value of an invalid form.
I didn't get any answers because this line was not commented out in my post and would have worked. Slap head............MODS feel free to delete this post if you think it is no help to anybody.