I was trying to set up form validation inside CakePHP. Model is recognized when entering submit form, but i have few problems:
When i enter any validation rule, the only thing that is checked is whenever in field is any text.
I can't do multiple rules per field - they are not working.
I can still type in artist field values, that are not alphanumeric...
Here is my Model code:
class Sounds extends AppModel {
public $validate = array(
'artist' => array(
'rule1' => array(
'rule' => 'notEmpty',
'message' => 'Please enter value',
'last' => false
),
'rule2' => array(
'rule' => 'alphaNumeric',
'message' => 'Please enter alphanumeric value'
)
)
);
Also in SoundController i have code, to check if form was validated:
if ($this->Sounds->validates()) { //action if validated } else {
$errors = $this->Sounds->validationErrors;
$this->set('errors_submit',$errors);
Related
I've declared my validation fields of my view in this way:
public $validate = array(
'myField' => array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'required' => true,
'message' => 'username required'
),
'unique' => array(
'rule' => 'isUnique',
'required' => 'create',
'message' => 'Username already used'
)
)
);
Is there a way to know (inside the relative controller class) when this message is fired?
Because if one of these rules is violated, I would like to perform some tasks, and not simply show message to the user.
Yes, first set the data to the model in your controller:
$this->ModelName->set($this->request->data);
Then, to check if the data validates, use the validates method of the model, which will return true if it validates and false if it doesn’t:
if ($this->ModelName->validates()) {
// it validated logic
} else {
// didn't validate logic
$errors = $this->ModelName->validationErrors;
}
To know more about validationErrors, go to cakephp Validating Data from the Controller article.
I'm using CakePHP 2.3.8 and I'm trying to figure out if there's a way to set certain validation rules to required on the fly.
For example, my User model has phone_number, username, email, and password validation. If a user wants to change their username, their phone number isn't required to do so. That means I can't set it to required, because then when changing a username, the phone_number will be expected to be present in the data.
public $validate = array(
'username' => array(
'minLength' => 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.',
),
'unique' => array(
'rule' => 'isUnique',
'message' => 'This email address is already in use'
)
),
'password' => array(
'rule' => array('minLength', '8'),
'message' => 'A password with a minimum length of 8 characters is required'
),
'phone_number' => array(
'rule' => array('valid_phone'),
'message' => 'Invalid phone number',
)
);
To get around this problem, in my controller for the corresponding action what I've been doing is checking to make sure the expected inputs have been posted. If not, set that index to null so that it is validated...such as
public function change_username(){
if(!isset($this->request->data['username'])){
$this->request->data['username'] = null;
}
$this->ExampleModel->set($this->request->data);
//if it wasn't posted, the username index will be created but set to null. This is my workaround for setting something to "required"
if($this->ExampleModel->validates() == true){
//do something
}
else{
//do something
}
}
While this works, I feel like it makes for a lot of extra coding, especially if I have a form that has a lot of inputs.
I've also tried to validate only the inputs that I need, but unless the data was posted, it ignores them. For example
if($this->ExampleModel->validates(array('fieldList' => array('phone')) == true){
.....
}
If "phone" wasn't posted, it doesn't validate it.
Is there any way to set required for a given input's validation to true on the fly? I found this article on using multiple validation rulesets and while it would accomplish what I want, there would be a lot of re-coding involved.
Before validation, can I set an input to required?
Firstly, in your Model validation rules you have phone_number but yet trying to validate phone, there aren't validation rules for phone.
It would be ideal request->data[] to match model fields, you can rebuild an array etc.
From book.cakephp:
This will add a single rule to the password field in the model. You can chain multiple calls to add to create as many rules as you like:
$this->validator()
->add('password', 'required', array(
'rule' => 'notEmpty',
'required' => 'create'
))
->add('password', 'size', array(
'rule' => array('between', 8, 20),
'message' => 'Password should be at least 8 chars long'
));
I want to use model validation.
lets i explain here clearly. in my view there is a file called "register.ctp". Also i have two table one is users and another is profiles, according to cakephp concept also i have two model that user model(User.php) and profile model(Profile.php).
My register.ctp contains the follow fields
name, email, address and phone all are mandatory - when i submit, name and email will store in users table and address and phone will store in profiles table
when i use model validation i have tried by using the below code that is working only for name and email but not working on for other fields.
here is my code for for model validation in user model(User.php)
public $validate = array(
'email' => array(
'blank' => array(
'rule' => 'notEmpty',
'message' => 'Please enter Email.'
)
),
'name' => array(
'rule' => 'notEmpty',
'message' => 'Please enter Name'
),
'address' => array(
'rule' => 'notEmpty',
'message' => 'Please enter Address'
),
'phone' => array(
'rule' => 'notEmpty',
'message' => 'Please enter Phone'
),
);
Thanks
You need to set the validation per model.
So in User.php:
public $validate = array(
'email' => array(
'blank' => array(
'rule' => 'notEmpty',
'message' => 'Please enter Email.'
)
),
'name' => array(
'rule' => 'notEmpty',
'message' => 'Please enter Name'
)
);
And in Profile.php:
public $validate = array(
'address' => array(
'rule' => 'notEmpty',
'message' => 'Please enter Address'
),
'phone' => array(
'rule' => 'notEmpty',
'message' => 'Please enter Phone'
)
);
And you need to validate both models in the Controller:
$this->User->set($this->data());
$valid = $this->User->validates();
$this->Profile->set($this->data);
$valid = $valid && $this->Profile->validates();
See these two model methods.
Model::validateAssociated() Validates a single record, as well as all its directly associated records.
Model::validateMany() validates multiple individual records for a single model
See Model::saveAll() as well. It can be used to validate the whole set of records and associated records. This will only validate but not save the reocrds as well:
$this->saveAll($data, array('validate' => 'only'));
I recommend you to read the whole documentation about saveAll() to understand how it works and what it will return when you only validate the data.
There is no need to manually validate each model one by one like noslone suggested. The single line above will do it as well.
I have a form on my homepage from an element in my Leads plugin. I have this in my Lead model:
public $validate = array(
'last_name' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Your custom message here',
'allowEmpty' => false,
),
),
'phone' => array(
'rocket' => array(
'rule' => array('phone', null, 'us')
),
),
);
My app is validating correctly because it's not posting to my database unless I fill in required fields. The problem is that the because my url isn't /leads/add it's not showing my custom error messages on my fields when I submit the form.
I think it has something to do with the fact that I'm using an element. Anyone have any ideas or had trouble with this before?
The rule should be notEmpty instead of notempty. What is working right now is the allowEmpty set to false which makes sure the field is not empty using !empty($field) || is_numeric($field).
I'm new to Cake and building an application to learn it. I'm having a few troubles with my user registration system. So far this is my registration code in my Users controller:
public function register() {
$this->set('title_for_layout', 'Register');
if ($this->request->is('post')) {
$this->User->create();
if ($this->User->save($this->request->data)) {
$this->Session->setFlash('The user has been saved');
$this->redirect(array('action' => 'register'));
} else {
$this->Session->setFlash('The user could not be saved. Please, try again.');
}
}
}
And within my User model I have this method where I hash the passwords:
public function beforeSave() {
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
}
return true;
}
This works, the user is added to my users table in my database with their username, email and hashed password. However, there are no checks done to make sure the username and email are unique.
From my limited understanding, I would need to add some validation rules to my User model to make sure the username and email fields are unique before they're entered into the table? At the moment I just have these validation rules:
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A username is required'
)
),
'email' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'An email is required'
)
),
'password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A password is required'
)
)
);
Also, my registration form has a Password (confirm) field called passwordConf. I would like to check if the user entered his passwords correctly before they're entered into the users table, but I'm not sure how to do that. I'm guessing that somewhere in my register method I need to check if the two passwords are the same.
Thanks for any help.
The isUnique rule will work with your username and email fields. Here is a sample of code that shows how to use multiple rules per field:
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'You must enter a username.'
),
'length' => array(
'rule' => array('between', 3, 15),
'message' => 'Your username must be between 3 and 15 characters long.'
),
'unique' => array(
'rule' => 'isUnique',
'message' => 'This username has already been taken.'
)
),
'password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'You must enter a password.'
),
'length' => array(
'rule' => array('minLength', '6'),
'message' => 'Your password must be at least 6 characters long.'
)
),
'email' => array(
'email' => array(
'rule' => array('email'),
'message' => 'Please enter a valid email address.'
)
)
);
As for comparing the passwords just edit your beforeSave callback and check the passwords against each other, returning true if they match and false if they do not. Something like this:
public function beforeSave() {
if (isset($this->data[$this->alias]['password'])) {
if($this->data[$this->alias]['password'] === $this->data[$this->alias]['passwordConf']) {
$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
return true;
} else {
return false;
}
}
return true;
}
CakePHP actually has a validation rule called isUnique, which you can use to check the username and e-mail. A list of built in rules can be found here. You can use this and the Data Validation Tutorial to check the user name and e-mail. As to checking if the passwords are the same, you MAY be able to use the EqualTo rule shown in the rules list, assuming you can make your validation rules on the fly every request.