Codeigniter Custom Form Validation - validation

this is my register method on controller to register a new user.
function register() {
$config_rules = array(
array(
'field' => 'txtEmail',
'label' => 'Email',
'rules' => 'required|valid_email'
),
array(
'field' => 'txtPassword',
'label' => 'Password',
'rules' => 'required|min_length[6]'
),
array(
'field' => 'txtRePassword',
'label' => 'Re-type Password',
'rules' => 'required|min_length[6]'
)
);
$this->form_validation->set_rules($config_rules);
if(isset($_POST['btnSubmit']) && $this->form_validation->run() == TRUE)
{
// insert query and redirect to registration success page
}
$this->load->view('users/register_form');
}
All the rules for form validation are work fine.
But, the problem is I can't do is to validate password and re-type password.
How make a custom form validation such as to check either
password and re-type password are same or not. Then return false for the validation and give error message telling that password and re-type password are not same through validation_errors().

You can specify the rule something like this:
$rules['password'] = "required|matches[passconf]";
In the above example, the field password will be matched with password confirm field passconf.
See the docs for more information.
http://ellislab.com/codeigniter/user-guide/libraries/form_validation.html

add:
matches[txtRePassword]
to the password rules, then you can use:
$this->validation->set_message('matches', 'New Passwords don\'t match');
to make a customer error message

Related

what would the following form validation rule mean ? I want a logic that even if one of the form posts are set...it should be allowed

$this->form_validation->set_rules('newusername', 'newfullname', 'newcity','newemail');
// is the set_rules correct. I want that if any one input field with above names are set. It should pass the validation . Please help me if there are any corrections.
May be you should read the manual again. If you want at least one of them filled, you'll need to write your own validation.
Using the following rules:
public $rules = array(
'newusername' => array(
'field' => 'newusername',
'label' => 'New User Name',
'rules' => 'trim|xss_clean|callback_needone'
),
'newfullname' => array(
'field' => 'newusername',
'label' => 'New Full Name',
'rules' => 'trim|xss_clean|callback_needone'
),
'newcity' => array(
'field' => 'newcity',
'label' => 'New City',
'rules' => 'trim|xss_clean|callback_needone'
),
'newemail' => array(
'field' => 'newemail',
'label' => 'New Email',
'rules' => 'trim|xss_clean|callback_needone'
)
)
in your controller you have to write
public function needone(){
if ( empty($this->input->post('newusername')) && empty($this->input->post('newfullname')) && empty($this->input->post('newcity')) && empty($this->input->post('newmail')) ) {
$this->form_validation->set_message('needone', 'At least one field must be entered');
return FALSE;
}
return TRUE;
}
Put the rule on any of the form's fields, or all of them to hilite those who are in the required group, it's up to you.
Each input field in your form, requires it's own validation rules. Which should look like this;
$this->form_validation->set_rules('field name', 'human name', 'rules');
https://ellislab.com/codeigniter/user-guide/libraries/form_validation.html#validationrules
So, you would have 4 set_rules functions, like this;
$this->form_validation->set_rules('newusername', 'New username', 'trim|xss_clean|required');
$this->form_validation->set_rules('newfullname', 'New full name', 'trim|xss_clean|required');
$this->form_validation->set_rules('newcity', 'New City', 'trim|xss_clean|required');
$this->form_validation->set_rules('newemail', 'New Email', 'trim|xss_clean|required');
https://ellislab.com/codeigniter/user-guide/libraries/form_validation.html#cascadingrules
Here's a rule reference, all the available rules;
https://ellislab.com/codeigniter/user-guide/libraries/form_validation.html#rulereference
Now, to check if ANY of the items are set, I would do this;
if ($this->input->post('newusername') OR $this->input->post('newusername') OR $this->input->post('newusername') OR $this->input->post('newusername'))
{
// One of them is set
}
else
{
// Nothing is set
}

CodeIgniter 2 and Ion Auth - edit own user account

I am using the latest Ion Auth files along with the latest version of CodeIgniter 2.
There is a function called edit_user within the auth.php Controller file. This function is restricted to use only by members within the "Admin" group, and any Admin member can edit any other member using the function via this URL...
/auth/edit_user/id
The problem is that I don't see any Controller function or View that allows a regular (non-Admin) user to edit their own account details.
Would this be a new Controller function I'd need to write (modify edit_user function?) or is this something that Ion Auth should already do? If so, how?
Here is the stock Ion Auth edit_user function contained within the auth.php Controller...
function edit_user($id)
{
$this->data['title'] = "Edit User";
if (!$this->ion_auth->logged_in() || !$this->ion_auth->is_admin())
{
redirect('auth', 'refresh');
}
$user = $this->ion_auth->user($id)->row();
//process the phone number
if (isset($user->phone) && !empty($user->phone))
{
$user->phone = explode('-', $user->phone);
}
//validate form input
$this->form_validation->set_rules('first_name', 'First Name', 'required|xss_clean');
$this->form_validation->set_rules('last_name', 'Last Name', 'required|xss_clean');
$this->form_validation->set_rules('phone1', 'First Part of Phone', 'required|xss_clean|min_length[3]|max_length[3]');
$this->form_validation->set_rules('phone2', 'Second Part of Phone', 'required|xss_clean|min_length[3]|max_length[3]');
$this->form_validation->set_rules('phone3', 'Third Part of Phone', 'required|xss_clean|min_length[4]|max_length[4]');
$this->form_validation->set_rules('company', 'Company Name', 'required|xss_clean');
if (isset($_POST) && !empty($_POST))
{
// do we have a valid request?
if ($this->_valid_csrf_nonce() === FALSE || $id != $this->input->post('id'))
{
show_error('This form post did not pass our security checks.');
}
$data = array(
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'company' => $this->input->post('company'),
'phone' => $this->input->post('phone1') . '-' . $this->input->post('phone2') . '-' . $this->input->post('phone3'),
);
//update the password if it was posted
if ($this->input->post('password'))
{
$this->form_validation->set_rules('password', 'Password', 'required|min_length[' . $this->config->item('min_password_length', 'ion_auth') . ']|max_length[' . $this->config->item('max_password_length', 'ion_auth') . ']|matches[password_confirm]');
$this->form_validation->set_rules('password_confirm', 'Password Confirmation', 'required');
$data['password'] = $this->input->post('password');
}
if ($this->form_validation->run() === TRUE)
{
$this->ion_auth->update($user->id, $data);
//check to see if we are creating the user
//redirect them back to the admin page
$this->session->set_flashdata('message', "User Saved");
redirect("auth", 'refresh');
}
}
//display the edit user form
$this->data['csrf'] = $this->_get_csrf_nonce();
//set the flash data error message if there is one
$this->data['message'] = (validation_errors() ? validation_errors() : ($this->ion_auth->errors() ? $this->ion_auth->errors() : $this->session->flashdata('message')));
//pass the user to the view
$this->data['user'] = $user;
$this->data['first_name'] = array(
'name' => 'first_name',
'id' => 'first_name',
'type' => 'text',
'value' => $this->form_validation->set_value('first_name', $user->first_name),
);
$this->data['last_name'] = array(
'name' => 'last_name',
'id' => 'last_name',
'type' => 'text',
'value' => $this->form_validation->set_value('last_name', $user->last_name),
);
$this->data['company'] = array(
'name' => 'company',
'id' => 'company',
'type' => 'text',
'value' => $this->form_validation->set_value('company', $user->company),
);
$this->data['phone1'] = array(
'name' => 'phone1',
'id' => 'phone1',
'type' => 'text',
'value' => $this->form_validation->set_value('phone1', $user->phone[0]),
);
$this->data['phone2'] = array(
'name' => 'phone2',
'id' => 'phone2',
'type' => 'text',
'value' => $this->form_validation->set_value('phone2', $user->phone[1]),
);
$this->data['phone3'] = array(
'name' => 'phone3',
'id' => 'phone3',
'type' => 'text',
'value' => $this->form_validation->set_value('phone3', $user->phone[2]),
);
$this->data['password'] = array(
'name' => 'password',
'id' => 'password',
'type' => 'password'
);
$this->data['password_confirm'] = array(
'name' => 'password_confirm',
'id' => 'password_confirm',
'type' => 'password'
);
$this->load->view('auth/edit_user', $this->data);
}
Unless I'm missing something, I ended up modifying the edit_user function within the auth.php Controller as follows.
I changed this line which checks to see that the user is "not logged in" OR "not an admin" before dumping them out...
if (!$this->ion_auth->logged_in() || !$this->ion_auth->is_admin())
{
redirect('auth', 'refresh');
}
...into this, which check to see that the user is "not logged in" OR ("not an admin" AND "not the user") before dumping them out...
if (!$this->ion_auth->logged_in() || (!$this->ion_auth->is_admin() && !($this->ion_auth->user()->row()->id == $id)))
This seems to be working...
Admin can edit all accounts
User can only edit his own account
and somebody not logged in, can't edit any account.
Edit: However, the user also has access to the "groups" setting and could simply put themself into the "admin" group. Not good.
Ion Auth's developer refers to the files he provides as working "examples". Therefore, it's up to the end-developer to edit Ion Auth to suit the needs of the project.
To prevent the user from being able to make himself an "admin" requires a simple change to the edit_user.php view file.
Verifies the user is already an "admin" before creating the checkboxes...
<?php if ($this->ion_auth->is_admin()): ?>
// code that generates Groups checkboxes
<?php endif ?>
Then you'll also need to thoroughly test and adjust as needed. For example, after editing a user profile, you're redirected to the auth view. Since the user doesn't have permission to see the auth view, there is a "must be an admin" error. In the controller file, you'll have to add the appropriate logic to properly redirect the user when they're not an "admin".
No Ion Auth doesn't do this as is - it's pretty light weight. But it's not hard to do and your on the right track, just grab that edit_user method and take out the admin checks and make it so the user can only edit their own account, just alter it so that it only updates user details for the currently logged in user.
Check the ion auth docs, have a crack at it and come back with some code if you have any problems.

Cakephp Email input validation exception

I have validation for the email input in my form but I would also like to create an exception for a string: "Not given" as some contact information do not have an email address. I know I can remove the email validation to do this but I want that validation there for new contacts. Those that do not have email addresses are some of the old contacts. So I would need an exception in order for me to add those contacts into this new system.
My current email validation in the model is as follows:
'email' => array(
'email' => array(
'rule' => array('email'),
'message' => 'Please enter a valid email address',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'uniqueEmail' => array(
'rule'=>'isUnique',
'message' => 'This email has already been added'
),
)
How do I implement this exception and where?
Any help would be great. Thanks!!
Just uncomment that 'allowEmpty' => false line and change it to true, this will permit the email filled to be submitted as an empty string.

CakePHP when using $model->save() validate rules and skip other rules

I'm using CakePHP 2.0 and I have a model that I use validation on it like this:
var $validate = array(
'title' => array(
'unique_rule'=>array(
'rule' => 'isUnique',
'on' => 'create',
'message' => 'This title has already been taken.'
),
'required_rule'=>array(
'required' => true,
'allowEmpty' => false,
'message' => 'The title field is required.'
)
)
);
, and in the controller I have an edit action and I use $model->save() to save date from $this->request->data, but it fails the isUnique validation rule, although it is not a new record insertion.
Is there any way to specify that it is an existing record, not a new one ?
If I got the question right you have to set the model's ID before calling $model->save(); so cakephp knows it's an update.
See http://book.cakephp.org/2.0/en/models/saving-your-data.html:
"Creating or updating is controlled by the model’s id field. If $Model->id is set, the record with this primary key is updated. Otherwise a new record is created:"
<?php
// Create: id isn't set or is null
$this->Recipe->create();
$this->Recipe->save($this->request->data);
// Update: id is set to a numerical value
$this->Recipe->id = 2;
$this->Recipe->save($this->request->data);
your validation array is wrong you haven't set a rule for 'required_rule' wich might trigger the isUnique error message.
var $validate = array(
'title' => array(
'unique_rule'=>array(
'rule' => 'isUnique',
'on' => 'create',
'message' => 'This title has already been taken.',
'last' => true
),
'required_rule'=>array(
'rule' => array('notEmpty'),
'message' => 'The title field is required.'
)
)
);
Also remember that using required=>true will NOT result check for actual data, it only wants the field to be present in the data-array and "" is also considered as present

cakePHP optional validation for file upload

How to make file uploading as optional with validation?
The code below validates even if i didn't selected any file.
I want to check the extension only if i selected the the file.
If i am not selecting any file it should not return any validation error.
class Catalog extends AppModel{
var $name = 'Catalog';
var $validate = array(
'name' => array(
'rule' => '/^[a-z0-9 ]{0,}$/i',
'allowEmpty' => false,
'message' => 'Invalid Catalog name'
),
'imageupload' => array(
'rule' => array('extension',array('jpeg','jpg','png','gif')),
'required' => false,
'allowEmpty' => true,
'message' => 'Invalid file'
),
);
}
thanks in advance
"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.
Concept:
In Controller, before validating, or saving (which does validation automatically by default) check if any file is uploaded. If not uploaded, then unset validator for the file field.
Sample code:
Controller
// is any image uploaded?
$isNoFileUploaded = ($this->request->data['Model']['field_name']['error'] == UPLOAD_ERR_NO_FILE) ? true : false ;
if ($isNoFileUploaded) {
$this->Model->validator()->remove('field_name');
}
Notes:
This solution comes under preprocessing as one of the two alternative approaches (preprocessing in controller, custom validation in model) suggested by #deceze's answer

Resources