CakePHP - How to check which validation rule failed? - validation

How can I check in my controller which one of the validation rules failed? I want to know if 'rule2' failed, based on the validation rule key.
public $validate = array(
'email' => array(
'rule1' => array(
'rule' => array('email', true),
'message' => 'Please enter a valid email address'
),
'rule2' => array(
'rule' => 'isUnique',
'message' => 'Email address already registered'
)
),
);
I know I can do debug($this->User->validationErrors) but all that shows is the message, and I don't want to check the message because I might change that in the future.
Is there any way to see that 'email.rule2' failed, based on the validation rule key?

for me it never made sense that the default param for last is false
IMO the correct approach is:
public $validate = array(
'email' => array(
'rule1' => array(
'rule' => array('email', true),
'message' => 'Please enter a valid email address',
'last' => true
),
'rule2' => array(
'rule' => 'isUnique',
'message' => 'Email address already registered'
)
),
);
ONLY check on unique if the email is valid in the first place.
and no, the message is the only thing returned. why is it important what failed?

I'm not sure if it does exactly what you need but try this:
$errors = $this->ModelName->invalidFields();

Related

Cakephp Form Validation empty indeces

Okay, so, in short, I'm trying to validate a form, as I've done a million times before with no trouble. However, I'm finding that on logging the validation errors, all the invalidated fields have an index in the validationErrors array but the messages are empty.
Yes, I've definitely set the validation messages in the model so I'm unsure why it's empty.
Here are my model validations:
public $validate = array(
'effective_policy_date' => array(
'date' => array(
'rule' => array('date'),
'message' => 'Invalid date format',
),
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Policy date required',
),
),
'business_address' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Business address required',
),
),
'city' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'City required',
),
),
'zip_code' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Zip code required',
),
),
'state_id' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'State required',
),
),
'contact_person' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Contact person required',
),
),
'phone' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Phone number required',
),
),
'email' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Email address required',
),
'email' => array(
'rule' => array('email'),
'message' => 'Invalid email format',
),
),
);
Here's the output of the validationErrors array after submitting the form with empty fields:
[AccountsRequest] => Array
(
[effective_policy_date] => Array
(
)
[policy_number_one] => Array
(
)
[policy_number_two] => Array
(
)
[policy_number_three] => Array
(
)
[policy_number_four] => Array
(
)
[business_address] => Array
(
)
[city] => Array
(
)
[zip_code] => Array
(
)
[state_id] => Array
(
)
)
For completeness sake, here's my Form->create array I use in the view and the controller action responsible for handling the form submission:
Form create() method
<?php
echo $this->Form->create(
'Request',
array(
'novalidate' => 'novalidate',
'action' => 'new_request',
'inputDefaults' => array(
'label' => false,
'div' => false,
'error' => array(
'attributes' => array(
'wrap' => 'label', 'class' => 'error'
)
)
)
)
);
?>
Controller action
public function new_request()
{
$this->page_id = 'requester_newform';
if($this->request->is('post'))
{
if($this->Request->saveAll($this->request->data, array('deep' => true, 'validate' => 'only')))
{
$this->Session->setFlash('Request saved successfully', 'flash/success');
}
else
{
$this->Session->setFlash('Could not save request. Please correct validation errors', 'flash/error');
}
}
}
You'll see some indeces in the validation array that aren't in the validationErrors, that's simply because I haven't quite finished converting the raw HTML to CakePHP forms.
Problem: The validationErrors array shouldn't be empty. It should contain the messages for the notEmpty rules and as a result there are empty error validation elements on the Form's frontend. Any ideas about what I'm doing wrong?
Aarg, how annoying. I've figured it out and it's a lesson well learnt.
For anyone having a similar issue in the future, make sure that your input fields conform to the relationships of the current form's Model.
For instance, in this example, my form's model is 'Request'. Request hasMany 'AccountsRequest'. So my form inputs were something like:
AccountsRequest.effective_policy_date
where it should have been
AccountsRequest.0.effective_policy_date
With this change, my model validation messages are now showing without issue.
I'd still love to know, however, why CakePHP even picked up those fields as invalid and further, if it was intelligent enough to pick up those fields as invalid why it didn't give me validation messages.
Oh well.....

CakePHP isUnique doesn't work

I prepare some registration form (the simplest) and in my Model i prepare some validation for email field:
'email' => array(
'mail' => array(
'rule' => array('email', true),
'required' => false,
'message' => 'Not correct e-mail!'),
'unique' => array(
'rule' => 'isUnique',
'message' => 'E-mail was registered!'))
But the rule isUnique doesn't work.
Addition i change in MySQL field email to unique, but still doesn't work.
I use CakePHP 2.3.7
Problem is when we use Translate behavior with model.
The query:
SELECT COUNT(DISTINCT(`User`.`id`)) AS count FROM `sometable`.`users` AS `User` INNER JOIN `sometable`.`i18n` AS `I18nModel` ON (`User`.`id` = `I18nModel`.`foreign_key` AND `I18nModel`.`model` = 'User' AND `I18nModel`.`locale` = 'pl') WHERE `User`.`email` = 'kicaj#kdev.pl'
Field email isn't translated.
Try this.
array(
'email' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'Provide an email address'
),
'validEmailRule' => array(
'rule' => array('email'),
'message' => 'Invalid email address'
),
'uniqueEmailRule' => array(
'rule' => 'isUnique',
'message' => 'Email already registered'
)
)
);
I copied your code and pasted it in my Model and it just worked fine!!! I don't think there is any error in it. I just added semicolon after your code. Here is the code that I have checked:
'email' => array(
'mail' => array(
'rule' => array('email', true),
'required' => false,
'message' => 'Not correct e-mail!'),
'unique' => array(
'rule' => 'isUnique',
'message' => 'E-mail was registered!')),
I think there would be some other error!!

CakePHP How to override already declared model validation error messages?

I can successfully put new messages in view files only if they are not present in model. I mean validations have to be in model, but messages attached to those validations should not be there.
Example model
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'required' => true, 'allowEmpty' => false,
'message' => 'Please enter a username.'),
'alpha' => array(
'rule' => array('alphaNumeric'),
'message' => 'The username must be alphanumeric.'),
'unique_username' => array(
'rule'=>array('isUnique', 'username'),
'message' => 'This username is already in use.'),
'username_min' => array(
'rule' => array('minLength', '3'),
'message' => 'The username must have at least 3 characters.')),
'email' => array(
...................
...................
and here's an example of view
echo $this->Form->input('username',array(
'label' => __d('app_users','Username'),
'error' => array(
'required' => __d('app_users', 'Please enter a username'),
.....................
.....................
));
So, my question is how can one make it into a work without removing 'message' => 'Please enter a username.' in a model but to TRULY OVERRIDE IT.
I mean validations have to be in model, but messages attached to those validations should not be there.
And how do you then have messages for a JSON API service? The text contained in validation has nothing to do with how your site looks so should not be in a view.
You can change the validation message from the model or from custom validation methods without much hassle and its all in the book

cakephp validate translated field

I have a model ex. posts that acts as translate and I want to validate the title which is a translated field.
How is this possible. The below does not work.
'title' => array(
'notempty' => array(
'rule' => array('notempty'),
),
));
Change rule name to camelCase: notEmpty and add message
you translate your message in /Locale default.po
'title' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'your translated message',
),
));
whats the big deal?

cakephp notempty and unique validation on field

I am working with cakephp. I need to add three validation on email field. First validation if email not given, second for valid email address, third if email address is given then it should be unique. Because its a signup form.
How I have add three validations on one field I try with the following code but it did not work for me.
public $validate = array(
'email' => array(
'email' => array(
'rule' => array('email'),
'message' => 'Invalid email address',
'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
)
),
'email' => array(
'rule' => 'isUnique',
'message' => 'Email already registered'
)
);
You have two identical indexes 'email' which PHP won't allow you. Change to something like:-
array(
'email' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'Provide an email address'
),
'validEmailRule' => array(
'rule' => array('email'),
'message' => 'Invalid email address'
),
'uniqueEmailRule' => array(
'rule' => 'isUnique',
'message' => 'Email already registered'
)
)
);
Otherwise only one of your rules will be used.
As of cakephp 3.0 in the entities table it should look something like this
namespace App\Model\Table;
public function validationDefault($validator)
{
$validator
->email('email')
->add('email', 'email', [
'rule' => [$this, 'isUnique'],
'message' => __('Email already registered')
])
->requirePresence('email', 'create')
->notEmpty('email', 'Email is Required', function( $context ){
if(isset($context['data']['role_id']) && $context['data']['role_id'] != 4){
return true;
}
return false;
});
return $validator;
}
}
function isUnique($email){
$user = $this->find('all')
->where([
'Users.email' => $email,
])
->first();
if($user){
return false;
}
return true;
}
What version of Cakephp do you use?
Because I think if you use 2.3, it should be:
public $validate = array( 'email' => 'email' );
with the field email in your SQL table set as a primary key.

Resources