So I'm trying to use a callback function with the Form_validation library in CodeIgniter (v2.1.4) to check whether a user with a given username or email exists in the database before creating a new user.
login.php (Controller)
function create_member()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'trim|required|min_length[4]|callback_value_check[USERNAME]');
if($this->form_validation->run() != FALSE)
{
// Validation passed; create the new user.
$this->load->model("members_model");
if($query = $this->members_model->create_member())
{
// Load the success page view.
}
else
{
// Reload the signup page view.
}
}
else
{
// Reload the signup page view.
}
}
function _value_check($value, $column)
{
$this->load->model("members_model");
if($this->members_model->check_exist_value($column, $value))
{
$this->form_validation->set_message('value_check', '%s is already taken.');
return FALSE;
}
else
{
return TRUE;
}
}
members_model.php (Model)
function check_exist_value($column, $value)
{
$this->db->where($column, $value);
$result = $this->db->get('MEMBERS');
if($result->num_rows() > 0)
{
// A user with that unique value already exists in the database.
return TRUE;
}
else
{
// There is no user with that unique value in the database.
return FALSE;
}
}
As seen in the code above, I'm only currently testing for an existing username. The standard validation messages appear correctly (i.e. required, min_length, etc). However, if I enter a value that I know to be already in the database (meaning the custom callback validation function should fail) I instead get an HTTP 500 error (Chrome's default 'Server error' page).
Does anyone have any insight as to why I'm getting an HTTP 500 error instead of seeing my custom error message?
I don't know why you are using you callback for the email/username unique check when codeigniter already provides this functionality in the form_validation class just add the unique rule check in the validation rules with the table name and column that has the emails/usernames also provide the table is column
$this->form_validation->set_rules('username', 'Username',
'trim|required|min_length[4]|unique[tablename.column_email_username,tablename.id]');
$this->form_validation->set_rules('username', 'Username',
'trim|required|min_length[4]|is_unique[tablename.column_email_username]');
Hope unique[tablename.column_email_username,tablename.id] does the job and you will not face the server error
OR try this for is_unique
Ahaha, turned out there was a type in the section reloading the view when the validation failed. Just needed to take a break and re-read through what I had to spot it!
Related
I cant be able to carry PUT operations on my codeigniter restful api app due to status code 400.
Here is the controller:
public function index_put(){
// for put you need to pass id as parameter
// Use validation library, instead of checking just for value.
$this->load->library('form_validation');
$this->form_validation->set_rules('id','ID','trim|required|integer');
$this->form_validation->set_rules('city','City','trim|required');
if($this->form_validation->run() == FALSE)
{
// send back list of validation errors.
$this->response(
$this->validation_errors(),REST_Controller::HTTP_BAD_REQUEST);
}
$update=$this->cities_model->update($this->post('id'),$this->post('city'));
if(!is_null($update))
{
$this->response(array('response' => 'content updated
successfully'),REST_Controller::HTTP_OK);
}
else
{
$this->response(array('error'=> 'sorry, technical error occurred, please
try again later...'), REST_Controller::HTTP_BAD_REQUEST);
}
}
}
I realized that PUT method is not working with me. Using POST method instead saved my day.
Hello all i was using form_validation Library in codeigniter inside my application. I am making a password retrieving function. I have made a submit form of the email . Now, on the email input field i want to apply these validations.
required
valid_email
check email exist or not.
For the 3rd one i am using call back function to check the database and it worked fine. But with the call back function valid_email is not functioning. This is my controller functions.
public function password_retrieve()
{
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email|callback__email_exists');
if ($this->form_validation->run() == false) {
$this->load->view('login_header');
$this->load->view('password_retrieve');
$this->load->view('login_footer');
} else {
}
} else {
$this->load->view('login_header');
$this->load->view('password_retrieve');
$this->load->view('login_footer');
}
}
function _email_exists($email)
{
$this->load->model('users_model');
$result = $result = $this->users_model->check_email_is_exist($email);
if (!$result) {
$this->form_validation->set_message(__FUNCTION__, 'This %s address does not exist!');
return false;
} else {
return true;
}
}
It should checked the valid_email rather than the going to the callback function.
In other mean i want to know what is the order of the rules. Is callback rule runs before the valid_email?
Try to remove "trim" and for check if email exist don't use another function. But use "is_unique[table_name.email]".
$this->form_validation->set_rules('email', 'Email', 'required|valid_email|is_unique[table_name.email]');
By Searching the official documentation and git repository i have found out that there is not a particular order in which a function will run in codeigniter. This means $this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email|callback__email_exists');
In this case valid_email will run after the callback__email_exists. There is not a order in which first trim, then required and then valid_email will run.
So what i have done is to make a new function in my callback function which runs after the required but before the check_email.
Answering this question so that in future people can get the benefit from it. Cheers!
I am new to CakePHP, and follow the tutorial of CakePHP to try login function, however there is no error message appear after I use the wrong username/password. Please help.
public function login()
{
if ($this->request->is('post')) {
$user=$this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect(['controller' => 'bookmarks']);
}
$this->Flash->error('Your username or password is incorrect');
}
}
By using FlashComponent's magic method __call() an element is required to exist under src/Template/Element/Flash.
In your case you called error(), therefore it uses src/Template/Element/Flash/error.ctp. Make sure element exists.
Either that or you are not calling $this->Flash->render() in your view (where you want the error message to be shown).
I have a helper function that checks if a username is valid.
In helper file:
if ( ! function_exists('valid_username'))
{
function valid_username($username)
{
$ci=& get_instance();
$ci->load->database();
if (empty($username) OR !preg_match("/^[a-z]([0-9a-z_-])+[0-9a-z]$/i", $username)) //Allowed a-z, 0-9, and underscores. Must end in a-z or 0-9.
{
$ci->form_validation->set_message('valid_username', 'Characters not valid.');
return FALSE;
}
$ci->db->select('username');
$ci->db->where('username', $username);
$ci->db->where('activated', 1);
$ci->db->where('banned', 0);
$ci->db->limit(1);
$query = $ci->db->get('users');
if ($query->num_rows() > 0) //if user exists
{
return TRUE;
}
else
{
$ci->form_validation->set_message('valid_username', 'The %s does not exist.');
return FALSE;
}
}
}
In my controller I am adding the helper to my form validation:
$this->form_validation->set_rules('username', 'Username', 'trim|required|xss_clean|min_length[2]|max_length[50]|callback_valid_username');
//add callback from helper function
function valid_username($username)
{
return valid_username($username);
}
This works well however I have to make the callback private like so:
$this->form_validation->set_rules('username', 'Username', 'trim|required|xss_clean|min_length[2]|max_length[50]|callback__valid_username');
function _valid_username($username)
{
return valid_username($username);
}
After making the callback private I get the following message upon submitting an invalid username:
Unable to access an error message corresponding to your field name.
What am I doing wrong here?
I'm not 100% sure why making the function private ruined your error messages, but I can suggest a workaround:
Form validation rules permit any function that accepts up to 1 parameter to be used as a validation or prep rule. So basically, anything that's available to the current script is available as a form validation rule as well, including your valid_username() function. Try this (just add it to your other rules):
$this->form_validation->set_rules('username', 'Username', 'valid_username');
So, you don't need the controller method as a wrapper, and you don't need to use callback_.See if that works for you.
Aside: I would suggest skipping the function_exists() call when you define valid_username(), unless you're sure you want to allow the function to be "overwritten".
You can use anything that is callable as a rule. Even if it is a function in a helper. Check it out
The right syntax is:
$this->form_validation->set_rules(
'username', 'Username', array('required', array('valid_username_callable', 'valid_username')));
In the helper, set error message if necessary like this:
$CI = &get_instance();
$CI->form_validation->set_message('valid_username_callable', 'Error message');
I am writing my form validation class using CodeIgniter. Is there any way so that I can get error messages in name value pair? For example, in a sample form there are four fields: user_name, password, password_conf, and timezone. Among them user_name and password validation has failed after executing the following:
$result = $this->form_validation->run();
If the above function returns false, I want to get the errors in name value pairs like the following:
Array
{
'user_name' => 'user name is required',
'password' => 'passord is required'
}
I truly want to form a JSON, which I can pass back to the AJAX call. I have a (dirty) solution: I can call validation methods one by one like the following:
$this->form_validation->required($user_name);
$this->form_validation->required($password);
Is there any other way, to get all the error messages at once in name value pair?
EDIT: I was suggested to do validation with jQuery from one of the answers:
jQuery will help in client side validation, but what about server side, there I am using CodeIgniter validation.
I have designed it so that:
I post all the values using AJAX.
Validate in server side (PHP).
Perform the desired operation if the inputs are valid; else return error to the user.
I have found one way myself by looking into the CodeIgniter code:
I have extended the library CI_Form_validation like: -
class MY_Form_validation extends CI_Form_validation
{
public function getErrorsArray()
{
return $this->_error_array;
}
}
I know, this is a hack, but will serve my need for the time. I hope CodeIginter team soon come up with an interface to access that array.
You can simply use,
$this->form_validation->error_array();
This is from the class reference documentation of CodeIgniter.
The solution I like best doesn't involve adding a function anywhere or extending the validation library:
$validator =& _get_validation_object();
$error_messages = $validator->_error_array;
Reference: http://thesimplesynthesis.com/post/how-to-get-form-validation-errors-as-an-array-in-codeigniter/
You should be able to call this at any point in your code. Also, it's worth noting there is a newer thread that discusses this as well.
You can create an private function in your controller
private function return_form_validation_error($input)
{
$output = array();
foreach ($input as $key => $value)
{
$output[$key] = form_error($key);
}
return $output;
}
and then in your validation method, just call this, here is mine
public function add_cat_form()
{
$this->output->unset_template();
$this->load->library('form_validation');
$this->form_validation->set_rules('name', 'Name', 'required');
if ($this->form_validation->run())
{
if (IS_AJAX)
{
$dataForInsert = $this->input->post();
if ($dataForInsert['parentid'] == -1)
{
unset($dataForInsert['parentid']);
}
$this->post_model->add_cat($dataForInsert);
echo json_encode('success');
} else
{
#in case of not using AJAX, the AJAX const defined
}
} else
{
if (IS_AJAX)
{
#This will be return form_validation error in an array
$output = $this->return_form_validation_error($this->input->post());
echo $output = json_encode($output);
} else
{
#in case of not using AJAX, the AJAX const defined
}
}
}
Seeing as code igniter validation gives you the error messages on a normal page refresh wouldn't it be better to use something like the jquery validation plugin which will validate entirely client side before sending the form? No AJAX necessary that way.
EDIT:
I'm not suggesting NOT DOING server side validation, just that posting with AJAX in order to validate isn't necessary and will reduce server hits if you do it client side. It will gracefully degrade to the regular page refresh with errors on or a success message.
there's already a correct answer but i think this one is more understandable on how to execute the process.
Do it in your Controller
$this->form_validation->set_rules('username', 'Username', 'required');
$this->form_validation->set_rules('password', 'Password', 'required');
if($this->form_validation->run() === FALSE){
$data['error'] = validation_errors();
}else{
//success
}
echo json_encode($data);
Do it in your JS
success:function(response){
if(response.error){
$('#notif').html(response.error);
}else{
//do stuff here...
}
}
and finally display the error corresponding to the given id in your js.
Do it in your HTML
<span id="notif"></span>
This might be way belated but I want to share a solution that I used in hope that it will benefit someone else.
Unfortunately, CodeIgniter's $this->form_validation->error_array() method returns only the errors that emanate from the set_rules() method. It does not account for the name of the form field that generated the error. However, we can leverage another of CodeIgniter's method $this->form_validation->error(), which returns the error(s) associated with a particular form field, by passing the name of the field as parameter.
//form validation rules
$this->form_validation->set_rules('f_name', 'First Name', 'trim|required',
['required' => 'First Name is required']
);
$this->form_validation->set_rules('l_name', 'Last Name', 'trim|required',
['required' => 'Last Name is required']
);
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email|is_unique[users.email]',
[
'required' => 'Email is required',
'valid_email' => 'Email format is invalid',
'is_unique' => 'Email already exists'
]
);
$error_arr = []; //array to hold the errors
//array of form field names
$field_names= ['f_name', 'l_name', 'email'];
//Iterate through the form fields to build a field=error associative pair.
foreach ($field_names as $field) {
$error = $this->form_validation->error($field);
//field has error?
if (strlen($error)) $error_arr[$field] = $error;
}
//print_r($error_arr);