issue in cakephp data validation on model - php

I am working on cakephp v2.3. While I am validation data by $this->User->validates it will always return false even if values are there.
Here is my validation rule
public $validate = array(
'first_name' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'This field cannot be left blank.',
'last' => true,
'required' => true,
),
'size' => array(
'rule' => array('maxLength', 50),
'message' => 'This field must be no larger than 50 characters long.'
),
),
'last_name' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'This field cannot be left blank.',
'last' => true,
'required' => true,
),
'size' => array(
'rule' => array('maxLength', 50),
'message' => 'This field must be no larger than 50 characters long.',
'allowEmpty' => true,
),
),
'email' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'This field cannot be left blank.',
'last' => true,
'required' => true,
),
'checkMail' => array(
'rule' => 'checkMail',
'message' => 'Please provide a valid email address.',
'last' => true,
),
'isUnique' => array(
'rule' => 'isUnique',
'message' => 'Email address already in use.',
'last' => true,
),
),
'password' => array(
'rule1' => array(
'rule' => array('minLength', 6),
'message' => 'Passwords must be at least 6 characters long.',
'required' => true,
),
),
'verify_password' => array(
'rule' => 'validIdentical',
),
'current_pass' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'This field cannot be left blank.',
'last' => true,
),
'match' => array(
'rule' => 'validICurrent',
)
),
'gender' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'This field cannot be left blank.',
'last' => true,
),
),
'mobile' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'This field cannot be left blank.',
'last' => true,
'required' => true,
),
'numeric' => array(
'rule' => 'numeric',
'message' => 'Please enter valid phone numbers.',
)
),
'image' => array(
'SizeLimit' => array(
'rule' => array('isUnderPhpSizeLimit', false),
'message' => 'File exceeds upload filesize limit',
),
'FormSizeLimit' => array(
'rule' => array('isUnderFormSizeLimit', false),
'allowEmpty' => true,
'message' => 'File exceeds form upload filesize limit'
),
'CompletedUpload' => array(
'rule' => array('isCompletedUpload', false),
'message' => 'File was not successfully uploaded'
),
'ValidExtension' => array(
'allowEmpty' => true,
'rule' => array('isValidExtension', array('gif', 'png', 'jpg', 'jpeg'), false),
'message' => 'File does not have a gif, png, ,jpg and jpeg extension'
)
),
);
and this is how I am validating
if ($this->request->is("post")) {
if (!empty($this->request->data)) {
if (!$this->User->validates($this->request->data)) {
$this->Session->setFlash(__('The Information could not be saved. Please, try again.'), 'message', array('class' => 'danger'));
$this->redirect(Router::url('/', true) . 'sign-up/');
}
}
When I try
die(debug($this->User->invalidFields()));
it will return
array(
'password' => '*****',
'last_name' => array(
(int) 0 => 'This field cannot be left blank.',
(int) 1 => 'This field cannot be left blank.'
),
'email' => array(
(int) 0 => 'This field cannot be left blank.',
(int) 1 => 'This field cannot be left blank.'
),
'mobile' => array(
(int) 0 => 'This field cannot be left blank.',
(int) 1 => 'This field cannot be left blank.'
)
)
This is the data I am passing
Array
(
[User] => Array
(
[role_id] => 2
[first_name] => kapil
[last_name] => sharma
[email] => kapiltest#mailinator.com
[password] => abc#123
[verify_password] => abc#123
[mobile] => 1234567890
[gender] => Male
[image] => Array
(
[name] => Screenshot_61.png
[type] => image/png
[tmp_name] => /tmp/phppYBJQF
[error] => 0
[size] => 50611
)
)
)

Your Validations seems fine to me But if we don't set the data in model some time that will cause this kind of issue.
Add below line before validating.
$this->User->set($this->request->data);
So code should look like
$this->User->set($this->request->data); //set data in model
if (!$this->User->validates()) {
$this->Session->setFlash(__('The Information could not be saved. Please, try again.'), 'message', array('class' => 'danger'));
$this->redirect(Router::url('/', true) . 'sign-up/');
}

Related

CakePHP skipping validation for an input

I followed this post for password confirmation, but CakePHP seems to be skipping over my re_password validation settings.
Here's my form
<?php echo $this->Form->create('User'); ?>
<fieldset>
<legend><?php echo __('Add Account'); ?></legend>
<?php
echo $this->Form->input('username');
echo $this->Form->input('email');
echo $this->Form->input('password');
echo $this->Form->input('re_password', array('type'=>'password', 'label'=>'Re-Enter Password', 'value'=>''));
echo $this->Form->input('role', array('type' => 'hidden', 'default' => 'user'));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
This is in my User model
function equalToField($array, $field) {
return strcmp($this->data[$this->alias][key($array)], $this->data[$this->alias][$field]) == 0;
}
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('minLength', '3'),
'message' => 'A username with a minimum length of 3 characters is required'
),
'unique' => array(
'rule' => 'isUnique',
'message' => 'This username has already been taken.'
)
),
'email' => array(
'email' => array(
'rule' => array('email'),
'message' => 'Please enter a valid email address.',
)
),
'password' => array(
'required' => array(
'rule' => array('minLength', '8'),
'message' => 'A password with a minimum length of 8 characters is required'
)
),
're_password' => array(
'required' => array(
'rule' => array('equalToField', 'password'),
'message' => 'Passwords do not match'
)
)
);
An error occurs if the minlength rule was triggered for the password field, but nothing ocurrs for the re_password field
I deleted the equalToField method just to see what would happen. I didn't even get an error so it seems as if re_password isn't even being looked at.
I'm not sure if this has anything to do with it, but when I added an additional rule to the password field regarding re_password, I got the following error: "Undefined index: re_password [APP/Model/User.php"
'password' => array(
'required' => array(
'rule' => array('minLength', '8'),
'rule' => array('equalToField', 're_password'),
'message' => 'A password with a minimum length of 8 characters is required'
)
),
Also, in my UsersController action I printed(this->request->data) and the re_password field is set.
For CakePHP2 you can use something like this:
public $validate = array(
'password' => array(
'length' => array(
'rule' => array('minLength', '8'),
'message' => 'Password should have at least 8 chars.'
)
),
'password_confirmation' => array(
'length' => array(
'rule' => array('minLength', '8'),
'message' => 'Password should have at least 8 chars.'
),
'compare' => array(
'rule' => array('validate_passwords'),
'message' => 'Passwords are not same.',
)
),
);
public function validate_passwords() {
return $this->data[$this->alias]['password'] === $this->data[$this->alias]['password_confirmation'];
}
This is working for me, Try with this..
public $validate = array(
'password' => array(
'minLength' => array(
'rule' => array('minLength', 4),
'message' => 'Password must be at least 4 characters long'
),
'maxLength' => array(
'rule' => array('maxLength', 50),
'message' => 'Password cannot be longer than 50 characters'
),
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'Please enter a password'
)
),
'confirm_password' => array(
'passwordMatch' => array(
'rule' => array('identicalFieldValues', 'password'),
'message' => 'The two passwords you entered do not match, please try again'
),
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'Please confirm your password by entering it twice'
)
)
);

Form validation with model but no table in cakePHP

I have a form that requires that all fields are filled in.
Upon submit, it should validate, before doing anything else. However, it submits even if there are some fields that were not filled in.
I've searched on here, but can't seem to find anything that is off use for me.
Here is my method in my InductionPpe controller:
public function request() {
if ($this->request->is('post')) {
$this->InductionPpe->set($this->request->data);
if($this->InductionPpe->validates()) {
// carry on
} else {
$this->validateErrors($this->InductionPpe);
$this->render();
}
}
}
My model has all the rules for the fields set up and completes the rest of the process just fine. But it does not validate.
Where do I start looking for the issue? And how do I fix it?
UPDATE
Validation rules in the InductionPpe Model:
class InductionPpe extends AppModel {
/**
* Validation rules
*
* #var array
*/
public $validate = array(
'hr_employee_id' => array(
'numeric' => array(
'rule' => array('numeric')
),
),
'name' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter your name.'
),
),
'shoes' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter the shoe size required.'
),
),
'reflective_jacket' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter the size reflective jacket required.'
),
),
'metaguards' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter the size of metaguards required.'
),
),
'glasses' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter the number of glasses required.'
),
),
'earplugs' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter the amount of earplugs reguired.'
),
),
'hardhats' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter the amount of hardhats required.'
),
),
'gloves' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter the amount of gloves required.'
),
),
'kit_bags' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter the amount of kit bags required.'
),
),
'dust_mask' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter the amount of dust masks required.'
),
),
'ppe_size' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter the size of the PPE items.'
),
),
'activities' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please specify which activities the PPE items are required for.'
),
),
'site' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter the site that you will be visiting.'
),
),
'project_number' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter the project number applicable.'
),
),
'date_required' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter the date that the PPE equipment is required.'
),
)
);
}
UPDATE 2
This is the validation debug I get (if I run debug($this->InductionPpe->validationErrors);).
array(
'name' => array(
(int) 0 => 'Please enter your name.'
),
'shoes' => array(
(int) 0 => 'Please enter the shoe size required.'
),
'reflective_jacket' => array(
(int) 0 => 'Please enter the size reflective jacket required.'
),
'metaguards' => array(
(int) 0 => 'Please enter the size of metaguards required.'
),
'glasses' => array(
(int) 0 => 'Please enter the number of glasses required.'
),
'earplugs' => array(
(int) 0 => 'Please enter the amount of earplugs reguired.'
),
'hardhats' => array(
(int) 0 => 'Please enter the amount of hardhats required.'
),
'gloves' => array(
(int) 0 => 'Please enter the amount of gloves required.'
),
'kit_bags' => array(
(int) 0 => 'Please enter the amount of kit bags required.'
),
'dust_mask' => array(
(int) 0 => 'Please enter the amount of dust masks required.'
),
'ppe_size' => array(
(int) 0 => 'Please enter the size of the PPE items.'
),
'activities' => array(
(int) 0 => 'Please specify which activities the PPE items are required for.'
),
'site' => array(
(int) 0 => 'Please enter the site that you will be visiting.'
),
'project_number' => array(
(int) 0 => 'Please enter the project number applicable.'
),
'date_required' => array(
(int) 0 => 'Please enter the date that the PPE equipment is required.'
)
)
And my form where these are entered:
<div class="inductionPpes form">
<?php
echo $this->Form->create('PpeRequest',array('type' => 'file')); ?>
<fieldset>
<legend><?php echo __(' PPE Request'); ?></legend>
<?php
echo $this->Form->input('name',array('value'=>$loggedInUsersName));
echo $this->Form->input('shoes');
echo $this->Form->input('reflective_jacket');
echo $this->Form->input('metaguards');
echo $this->Form->input('glasses');
echo $this->Form->input('earplugs');
echo $this->Form->input('hardhats');
echo $this->Form->input('gloves');
echo $this->Form->input('kit_bag');
echo $this->Form->input('dust_masks');
echo $this->Form->input('ppe_size');
echo $this->Form->input('activities',array('label'=>'Type of activities that will be undertaken'));
echo $this->Form->input('additional',array('label'=>'Additional PPE Requirements'));
echo $this->Form->input('site',array('label'=>'Type of Site'));
echo $this->Form->input('project_number');
echo $this->Form->input('date_required');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
Try changing the notempty rule to this
'notempty' => array(
'required' => true,
'allowEmpty' => false, // this may not be neccessary
'rule' => 'notEmpty',
'message' => 'Please enter the ...',
)
The problem may be that you wrapped validation rule names in an array. AFAIK only rules with parameters should be entered this way.
Also I don't know about $this->validateErrors and whether such variable exists but I always use $this->Model->validationErrors
Try this (with all your notempty validations)
'name' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please enter your name.',
'required' => true,
'allowEmpty' => false
),
),
putting required and allowEmpty on bottom. Also, reading your comments, you mention the error blocks doesn't show. Read this post, if you do $this->Model->save(), it'll take care of that, otherwise you'll have to do it.

Looking for invalidFields() with CakePHP

I'm trying to find out how to get the actual message from my validate() array which contains all the rules to validate a submission within my model.
Basically I'm POSTing ajaxily and I'd like to return all of the error messages in the form that have failed validation, but it's sending them anyway even when they have passed validation.
So in my
SubmissionsController I'm doing this:
if ($this->request->is('ajax')) {
$formData = $this->Submission->invalidFields();
$this->set(compact('formData'));
}
In my Submission model I have:
var $validate = array(
'title' => array(
'title' => array(
'rule' => 'notEmpty',
'required' => true,
'allowEmpty' => false,
'message' => 'Please enter a title'
),
'minLength' => array(
'rule' => array('minLength', 5),
'message' => 'Please make your title longer (e.g. IJL John F. Kennedy donated his presidential salary to charity)'
),
'maxLength' => array(
'rule' => array('maxLength', 300),
'message' => 'Your title needs to be shorter'
),
),
'description' => array(
'shortDescription' => array(
'rule' => array('shortDescription'),
'message' => 'Your description needs to be longer'
),
'longDescription' => array(
'rule' => array('longDescription'),
'message' => 'Your description needs to be shorter'
),
),
'source' => array(
'source' => array(
'rule' => 'notEmpty',
'required' => true,
'allowEmpty' => false,
'message' => 'Enter a valid source URL (e.g. http://en.wikipedia.org/wiki/Penguins)'
),
'website' => array(
'rule' => 'url',
'message' => 'Enter a valid source URL (e.g. http://en.wikipedia.org/wiki/Penguins)'
),
),
'category' => array(
'category' => array(
'rule' => 'notEmpty',
'required' => true,
'allowEmpty' => false,
'message' => 'Please choose a category'
)
)
);
In my Submissions/json/submit.ctp file I have:
<?php
$fragment = $this->element('errors/flash_error');
$toReturn = array(
'formData' => $formData
);
echo json_encode($toReturn);
If I enter in a valid title or any other valid field, I still am getting back the error message instead of nothing.
Is there something I'm missing that invalidFields() needs in order to NOT return fields which HAVE passed validation?
EDIT:
As Leo suggested below, I wasn't calling save before invalidFields()
The correct code should be:
if ($this->Submission->save($this->request->data)) {
$formData = null;
} else {
$formData = $this->Submission->invalidFields();
}
$this->set(compact('formData'));
You're calling invalidFields() without validation either by a save() call or validates()!

CakePHP: anyway to tell why Model->validates() returns false?

If Model->validates() returns false is there an easy way to know why?
I am trying to save some data but it will not save. As it turns out, it is not validating either. If I turn off validation it saves. I need to validate it though, but I can not tell why it is not validating?
I used this code:
if($this->User->create($user) && !$this->User->validates())
{
debug($user);
}
So if it doesn't validate it tells me what the data is.
It prints out this:
Array
(
[User] => Array
(
[first_name] => Tim
[last_name] => Zahn
[phone] => 8833323235
[email] => t#z.com
[password] => ert
)
[Confirm] => Array
(
[email] => t#z.com
[password] => ert
)
)
Which looks like it should be passing validation.
Also if needed I can post my Model source as well.
Update:
Here is the model. I am using the multivalidatable behavior. I have tried using the default and register validation sets:
class User extends AppModel
{
var $actsAs = array('Multivalidatable');
var $hasOne = 'WishList';
var $hasMany = array(
'Address' => array(
'conditions' => array('NOT' => array('Address.deleted' => '1')),
'order' => array('Address.is_billing DESC')
)
);
var $validate = array(
'first_name' => array(
'rule' => 'notEmpty'
),
'last_name' => array(
'rule' => 'notEmpty'
),
'password' => array(
'passRule1' => array(
'rule' => 'notEmpty',
'message' => 'Please enter a password'
),
'passRule2' => array(
'rule' => array('identicalFieldValues', 'password'),
'message' => 'Passwords do not match'
)
),
'email' => array(
'emailRule1' => array(
'rule' => 'email',
'message' => 'You must specify a valid email address'
),
'emailRule3' => array(
'rule' => array('identicalFieldValues', 'email'),
'message' => 'Emails do not match'
)
)
);
var $validationSets = array(
'register' => array(
'first_name' => array(
'rule' => 'notEmpty'
),
'last_name' => array(
'rule' => 'notEmpty'
),
'password' => array(
'passRule1' => array(
'rule' => 'notEmpty',
'message' => 'Please enter a password'
),
'passRule2' => array(
'rule' => array('identicalFieldValues', 'password'),
'message' => 'Passwords do not match'
)
),
'email' => array(
'emailRule1' => array(
'rule' => 'email',
'message' => 'You must specify a valid email address'
),
'emailRule2' => array(
'rule' => 'isUnique',
'message' => 'That email address is already in our system'
),
'emailRule3' => array(
'rule' => array('identicalFieldValues', 'email'),
'message' => 'Emails do not match'
)
)
),
'billing' => array(
'email' => array(
'emailRule1' => array(
'rule' => 'email',
'message' => 'You must specify a valid email address'
),
'emailRule3' => array(
'rule' => array('identicalFieldValues', 'email'),
'message' => 'Emails do not match'
)
)
)
);
public function beforeValidate()
{
parent::beforeValidate();
// if password is empty reset from hash to empty string
if (isset($this->data['User']['password']) && $this->data['User']['password'] == Security::hash('', null, true)) {
$this->data['User']['password'] = '';
}
return true;
}
function identicalFieldValues($field=array(), $compare_field=null)
{
foreach ($field as $key => $value)
{
$v1 = $value;
$v2 = $this->data["Confirm"][$compare_field];
if ($compare_field == 'password' && $v2 != '')
{
$v2 = Security::hash($v2, null, true);
}
if ($v1 !== $v2)
{
return false;
}
else
{
continue;
}
}
return true;
}
}
I'd start with something like this:
if($this->User->create($user) && !$this->User->validates())
{
debug($user);
debug($this->User->validationErrors);
}
That should tell you exactly which field or fields aren't passing validation and why.
Do you have a message set up in the validation so it can tell you where it is failing, for example:
'password' => array(
'rule' => array('minLength', '8'),
'message' => 'Mimimum 8 characters long'
),
Also, if you have AUTH on, it may be encrypting the password.
Also, you should assert validate BEFORE you attempt to create/save.

cakePHP validation

I am working on a cakePHP project and have set up my data validation. The problem i have is that i keep getting an error from the core/model of cakePHP.
The error is:
Notice (8): Undefined offset: 0 [CORE/cake/libs/model/model.php, line 2435]
if (is_array($validator['rule'])) {
$rule = $validator['rule'][0];
My validation rules look like this:
var $validate = array(
'name' => array(
'rule' => array('maxLength' => 80),
'required' => true,
'message' => 'Please enter your name'
),
'address1' => array(
'rule' => array('maxLength' => 80),
'required' => true,
'message' => 'You forgot your address'
),
'address2' => array(
'rule' => array('maxLength' => 80),
'message' => 'Your address can\'t be that long?'
),
'city' => array(
'rule' => array('maxLength' => 80),
'required' => true,
'message' => 'Your city can\'t be that long?'
),
'zip' => array(
'rule' => array('postal', null, 'us'),
'required' => true,
'message' => 'Your zip code is not in the corect format.'
),
'phone' => array(
'rule' => array('phone', null, 'us'),
'required' => true,
'message' => 'Your phone number is not in the corect format.'
),
'email' => array(
'rule' => 'email',
'required' => true,
'message' => 'Please enter a valid email address.'
),
'seats' => array(
'rule' => 'numeric',
'required' => true,
'message' => 'You forgot to let us know how many seats you need. If you will not be attending please enter a zero (0)'
),
'seat_with' => array(
'rule' => array('maxLength' => 80),
'message' => 'Please keep this field below 80 charcters.'
),
'cc_name' => array(
'rule' => array('maxLength' => 80),
'required' => true,
'message' => 'Did you forget something?'
),
'cc_number' => array(
'rule' => array('cc', 'all', false, null),
'required' => true,
'message' => 'Your credit card number is not in the correct format.'
),
'cc_expiration' => array(
'rule' => array('date', 'my'),
'required' => true,
'message' => 'The correct answer will be in the following format MM/YYYY'
),
'cc_cvv' => array(
'rule' => 'numeric',
'required' => true,
'message' => 'Numbers only please.'
)
);
Any help is much appreciated.
Your problem is in the rule syntax:
array('maxLength' => 80)
Just like your other rules, it's ,, not =>: array('maxLength', 80).
BTW, my city can be that long: http://en.wikipedia.org/wiki/Krung Thep Mahanakhon Amon Rattanakosin Mahinthara... ;-)

Categories