I have just started on learning how to use CodeIgniter and have never use any framework before so I only know a bit of how is the flow. Right now I have 1 issue that I want to set the input username to lowercase and I do not have any idea how to write the function for the convert_lowercase().
Below is my code:
public function signup_validation()
{
$this ->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'required|trim|is_unique[userinfo.username]|convert_lowercase');
$this->form_validation->set_rules('password', 'Password', 'required|trim');
$this->form_validation->set_rules('cpassword', 'Confirm Password', 'required|trim|matches[password]');
$this->form_validation->set_message('is_unique', 'That Username Already Exists.');
if($this->form_validation->run()){
}else{
$this->load->view('signup');
}
}
public function convert_lowercase()
{
strtolower($this->input->post('username'));
}
I am not sure am I doing the right way.
And is it best to just put the strtolower in the set_rules parameter? Or it is best to put in a function?
And if separate it, how should it be done and how do I get the final username data to insert into database?
Any kind souls out there can help me on this?
Thanks in advance.
You can provide php native functions for form validation to CodeIgniter. Here is how your code should be
public function signup_validation()
{
$this ->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'required|trim|is_unique[userinfo.username]|strtolower');
$this->form_validation->set_rules('password', 'Password', 'required|trim');
$this->form_validation->set_rules('cpassword', 'Confirm Password', 'required|trim|matches[password]');
$this->form_validation->set_message('is_unique', 'That Username Already Exists.');
if($this->form_validation->run()){
}else{
$this->load->view('signup');
}
}
You should check their documentation on form validation: http://ellislab.com/codeigniter%20/user-guide/libraries/form_validation.html
add callback_ to the rules.
$this->form_validation->set_rules('username', 'Username', 'required|trim|is_unique[userinfo.username]|callback_convert_lowercase');
and the callback function should return some value.
public function convert_lowercase() {
return strtolower($this->input->post('username'));
}
I will try to explain the best I can! Have you set up your database config file correctly? Have you set up the database correctly? Make sure that is all good before you do this..
Here is a bit of what is going on
if($this->form_validation->run()){
//Right here is what happens if the form passes your test!
$this->insert_user();
}else{
$this->load->view('signup');
}
if($this->form_validation->run()) takes the rules you gave it and if it returns "true" it runs in that if statement otherwise it will return you to the signup page
Here is the function that I set an example for
public function insert_user()
{
$data = array(
'username' => strtolower($this->input->post('username')),
'password' => $this->input->post('password'),
);
$this->db->insert('users', $data);
}
I also suggest you look into encrypting your passwords and other CI documentation, it is fantastic
Regarding Codeigniter 4 it is no longer possible to modify data during validation.
They add this information in official documentation :
"You can also use any native PHP functions that return boolean and permit at least one parameter, the field data to validate. The Validation library never alters the data to validate."
Related
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!
For some reason when I run the submit function it returns an error that tells me the form did not submit properly but while looking over the docs I was not able to find out how to display what rules were not validated correctly.
{"output_status":"Error","output_title":"Form Not Validated","output_message":"The form did not validate successfully!"}
This is my controller code:
public function form_is_valid()
{
/* Set validation rules for post data */
$this->form_validation->set_rules('username', 'Username', 'trim|required|xss_clean|min_length[6]|max_length[12]|regex_match[/[a-z0-9]/]');
$this->form_validation->set_rules('password', 'Password', 'trim|required|xss_clean|min_length[6]|max_length[12]|regex_match[/[a-z0-9]/]');
//$this->form_validation->set_rules('remember', 'Remember Me', 'trim|xss_clean|integer');
/* Form validation passed */
return $this->form_validation->run();
}
public function submit()
{
if (!$this->form_is_valid())
{
$this->output('The form did not validate successfully!', 'Form Not Validated', 'Error');
return;
}
... rest of submit function code...
}
The posted values are:
password testpass
username testuser
I was able to with the comments in this question thread use the function with use of the user guide on the codeigniter website. And find out that I was forgetting the username had to be atleast 6 characters long.
About a week ago i started experimenting with CodeIngiter, because i want to learn OOP. I thought i was on the right track, but now i begin to doubt that. The reason is, i have a controller for Members, which is becoming quite a large file. This is because i want my urls to be like members/login , members/register etc.
Here is my controller:
<?php
class Members extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('users');
}
public function index()
{
}
public function register()
{
$this->load->helper(array(
'form',
'recaptcha'
));
$this->load->library('form_validation');
$data['title'] = "Register a free account - Become an Author";
$data['titlesucces'] = "Thanks for registering";
$this->form_validation->set_rules('fname', 'First name', 'required');
$this->form_validation->set_rules('lname', 'Last name', 'required');
$this->form_validation->set_rules('password', 'Password', 'required');
$this->form_validation->set_rules('passwordconf', 'Password Confirmation', 'required');
$this->form_validation->set_rules('email', 'Emailaddress', 'required|is_unique[users.email]|valid_email');
$this->form_validation->set_rules('recaptcha_challenge_field', 'Captcha', 'required|recaptcha_matches');
if (!$this->form_validation->run()) {
$this->load->view('header', $data);
$this->load->view('register', $data);
} else {
$this->users->register_new_member();
$this->load->view('register_succes', $data);
}
}
public function login()
{
$data['title'] = "Login";
$data['fail'] = "";
$this->load->helper('form');
$this->load->library('form_validation');
$this->form_validation->set_rules('email', 'Emailaddres', 'required');
$this->form_validation->set_rules('password', 'Password', 'required');
if (!$this->form_validation->run()) {
$this->load->view('login', $data);
} else {
if ($this->users->do_login($this->input->post('email'), $this->input->post('password'))) {
$this->load->view('login', $data);
} else {
$data['fail'] = "Emailaddress or password is incorrect";
$this->load->view('login', $data);
}
}
}
public function logout()
{
$this->session->sess_destroy();
redirect('/members/login/', 'refresh');
}
public function addarticle()
{
if ($this->users->logged_in()) {
$this->load->helper('form');
$this->load->library('form_validation');
$this->form_validation->set_rules('title', 'Title', 'required|max_length[200]|min_length[10]');
$this->form_validation->set_rules('intro', 'Intro', 'required|min_length[40]|max_length[50]');
$this->form_validation->set_rules('cat', 'Category', 'required');
$this->form_validation->set_rules('body', 'Article', 'required|min_length[3000]|link_check');
$this->load->model('categories');
$data['title'] = "Add a new article";
$data['cats'] = $this->categories->get_all_categories();
if (!$this->form_validation->run()) {
$this->load->view('addarticle', $data);
} else {
$this->load->model('articles');
$this->articles->add_new_article();
$this->load->view('welcome');
}
} else {
redirect('/members/login/', 'refresh');
}
}
}
?>
As you can see its quite a big file already, but it will only get bigger. Now my question to you guys is: is this still the right MVC way or am i doing something wrong?
Thanks!
I have created a few critical high availability systems in CodeIgniter, and found it wonderfully powerful and greatly flexible for my particular projects. It does not have the large baggage that comes with other "enterprise" frameworks like ZF (Not to be saying ZF doesn't have its own advantages).
Like zeusakm said, your controller is not that huge. However it all depends also, on which side of the fat controller-lean model/lean controller-fat model debate you stand at (along with the other zillion variations/styles that are out there). Personally, I prefer to keep my controller as lean as possible. If I feel my controller is doing too many things, and becoming bloated sometimes I move some of those functionalities into helpers (instead of models), mainly because I like to have my models reflect business objects. Also, when some of these tasks can be coupled together into a more well formed entity, sometimes I merge them into libraries (my own or third party)
I guess the main idea is that there is no silver-bullet right way for MVC - what works for one project might not be a good idea for another. There are many factors to weigh in. End of the day, if your code is easily maintainable, if a person can read and understand the way it is laid out without too much hassle, if people with different roles/responsiblites like Programmers/Frontend HTML designers/ Backend database coders can all work together using the framework easily without stepping (too much) on each others toes, then yes I would say your MVC is doing its job.
Also keep in mind that how URLS map out into the MVC is only one aspect of the system. This can be handled in a myriad of different ways, from mock controllers which map into a detailed model, htaccess rewrites, sometimes even MVC routers help you configure how you want URLs to resolve..
You are doing completelly right things, and this file isn't big anough yet, and I doubt it will be. I've programmed on CodeIgniter - great and light-weight FW, and there is a cool MVC model/pattern workarounds. So just keep going.
Another thing while Your file/controller didn't achive 1000-1500 lines of code do not bother Your-self with this question.
The MVC is not actually what Your controller contains, rather than whole bunch of things Models(DB Queries, Herlper Functions), Views(Templates/GUI) and Controller(Logic) - keep that in mind and do not worry about anything at this point.
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);