Validate any kind of data using the same way as Form Validation Code Igniter Library. Move your data validation from Controllers to Models and achieve a Fat Model skinny Controller Theme in Code Igniter
Update
It seems that the new version of Code Igniter breaks the Data validation class. The fix is relatively simple, just change the problematic “private” methods to public and you are done. A blog reader, Samer Bechara has fixed the Data Validation class by having it extend the Form Validation class. You can find his version of the Data Validaiton Class in the Downloads section of this post. Thank you Sam!
I love Code Igniter! It’s one of the fastest ways to create nicely structured and modular web applications out there. I love its simplistic approach and how fast you can get ready with development. Just unzip edit configuration files and you’re done.. no CLI tools needed (rings a bell Zend, Cake, Symf … ?)
One of the most used libraries out there in Code Igniter is the Form Validation class. It allows us to quickly write rules which validate data coming from our dear users. It’s very convenient, featuring callbacks. Unfortunately, Form Validation class breaks the “Fat Model , Skinny Controller” scheme that MVC web applications should follow for a number of reasons. Actually, it requires that you use the form data validation in the Controller and use the model as a Data Abstraction Layer.
Personally, I believe that the Model and only the model should be able to validate the data it’s using! This way, you can easily enforce data integrity rules in model level, and make global changes to your Data Model quickly and easily. Moreover, you can copy Models around various projects easily, thus following the DRY concept and making your life easier.
That’s why I have created the Data Validation class, which features the complete functionality of the Form Validation class, but without restricting the validation rules to the $_POST array. And, as I don’t want to break legacy code, I have added some methods which will allow you to propagate Data Validation validation results to Form Validation, for use in views!
Installation
Copy the following files:
- data_validation.php file in the \libraries directory of your application
- data_validation_helper.php in the \helpers directory of your application
- data_validation_lang.php in the \language\english directory of your application
Form validation so far
Consider a Users_model which allows you to add rows to a specific table in your database ( TABLE `users` ( `id` INT NOT NULL AUTOINCREMENT, `name` VARCHAR(20), `surname` VARCHAR(50)) )and to check if a name and surname is unique
class Users_model extends CI_Model {
function add_user($name,$surname)
{
$this->db->insert('users',array('name'=>$name,'surname'=>$surname);
}
function is_name_surname_unique($name,$surname)
{
$ret = $this->db->from('users')->where('name',$name)->
where('surname'=>$surname)->get("id");
if ($ret->num_rows()==0)
return true;
return false;
}
There’s also a controller calling this model.
class Users extends CI_Controller{
function add_user()
{
if ($this->input->post('submit'))
{
$this->load->library('form_validation');
$this->form_validation->set_rules('name','Name','trim|required|
callback_name_unique[surname]');
$this->form_validation->set_rules('surname','Surname','trim|required');
if ($this->form_validation->run()==TRUE)
{
$this->load->model('Users_model');
$this->Users_model->add_user(
$this->input->post('name'),
$this->input->post('surname')
);
$this->load->view('success');
return;
}
}
$this->load->view('add_form');
}
function name_surname_unique($name,$surname)
{
$this->load->model('Users_model');
return $this->Users_model->is_name_surname_unique($name,$surname);
}
}
Finally, there’s a form handling data input , a typical form
echo form_open();
echo "<div> Name : " . form_input('name',$this->input->post('name'));
echo form_error('name', '', '') . "</div>";
echo "<div>Surname : " . form_input('surname',$this->input->post('surname'));
echo form_error('surname', '', '') . "</div>";
echo form_submit('submit','Add user');
If you look at the later files, you can pretty much see that the Controller is fat and the model is skinny. All data validation is present in the controller and the model just cares to insert the table to the database. Moreover we use two functions to validate that the name and surname combination is unique!
Moving validation to the model level
Now let’s try to move validation down to our model level:
class Users_model extends CI_Model
{
function add_user($user_name,$user_surname)
{
$this->load->library('data_validation');
//Feed our library with an array containing the values to be validated
$this->data_validation->import_data_array(get_defined_vars());
//get_defined_vars() will return the following
//array('user_name'=>$user_name,'user_surname'=>$user_surname);
//Specify where Data validator should try to find callbacks
$this->data_validation->set_validator_object($this);
//You are free to replace $this with any object loaded in the $CI factory object!
$this->data_validation->set_rules('user_name','Name','trim|required|
callback_name_surname_unique[user_surname]');
$this->data_validation->set_rules(user_surname','Name','trim|required');
if ($this->data_validation->run()==TRUE)
{
$this->db->insert('users',array('name'=>$name,'surname'=>$surname));
return TRUE;
}
else
return FALSE;
}
function name_surname_unique($name,$surname)
{
//Get the value from the data validator data array
$surname_value = $this->data_validation->_data_array[$surname];
$ret = $this->db->from('users')->where('name'=>$name)->
where('surname'=>$surname_value)->get("id");
if ($ret->num_rows()==0)
return TRUE;
$this->data_validation->set_message('name_surname_unique',
'This user is already in the database');
return FALSE;
}
}
That’s it, we have moved the data validation right in our model, thus making it portable. So our controller loses some weight:
class Users extends CI_Controller{
function add_user()
{
if ($this->input->post('submit'))
{
$this->load->model('Users_model');
if ($this->Users_model->add_user($this->input->post('name'),
$this->input->post('surname')))
{
$this->load->view('success');
}
}
$this->load->view('add_form');
}
The above code works fine, but we still have a problem! The view has no idea on what error messages to display in case of invalid data.
Moreover, we would not like to break legacy code. So, the Form validation library needs to somehow reflect on the state of our Data Validator! We can do that by using the “propagate_to_form_validation()” method, after we have instructed our library how to map fields to post values.
So, we change the controller to this:
class Users extends CI_Controller{
function add_user()
{
if ($this->input->post('submit'))
{
$this->load->model('Users_model');
if ($this->Users_model->add_user($this->input->post('name'),
$this->input->post('surname')))
{
$this->load->view('success');
}
else
{
//First of all we need to tell the data validator how $_POST variables
//are mapped to the model methods
//We create an array with all the fields following this pattern
// array( "model_method_parameter_name"=>"post_variable_name");
$post_map = array("user_name"=>"name","user_surname"=>"surname");
//Then we feed this array to the data validation object.
$this->data_validation->map_to_post($post_map);
//And we instruct the data validator to propagate error messages
//to the form validator
$this->data_validation->propagate_to_form_validation();
}
}
$this->load->view('add_form');
}
}
That’s it actually! We are now free to transparently use all the helpers provided by Form Validation library, such as set_value() form_error() or validation_errors();
Download
Download Code Igniter Data Validator Library (90)
Download Data validator Test application (79)
Download Data validation class - Form validation extension (29) (enhanced by Samer Bechara)




Crazy that you just posted this as I was searching for something like this! Thank you so much!
Welcome!
Feel free to show us any ways you have used it
Your class is just what I was searching for. However, after upgrading to codeigniter 2.1.0 today, I got a fatal error “Unable to access protected property”. I fixed that by having the library extend the Form Validation method.
I ran a diff between CodeIgniter’s form validation library and yours, and I can see that the changes are minimal. Wouldn’t it be better to implement this as an inherited library of Form Validation? It would greatly simplify your code.
Thank you for your valuable feedback. Indeed, the new CodeIgniter breaks the data validation class, but I will release a fix really soon.
I agree it would be better to implement this as an inherited library from Form Validation, but I specifially remember facing some problems with I tried to extend it (at least in Code Igniter 2) because of protected properties. Moreover, someone implementing fat models may not need to load the Form Validation.
I have already fixed this issue for my own project. I have implemented it as an inherited class from the form validation class. Where should I send you this? It might help you accelerate things.
Thank you for your interest and work on the inherited class. I have sent you an email, please email me the rar so I can upload here (of course, full credit goes to you!)
Just wanted to let you know that I haven’t received your email.
In any case, I have pasted the code at pastebin so you could use it:
http://pastebin.com/kmaWZxbV
Let me know if you encounter any issues.
Thanks for your code. Nice share.
You are welcome! Glad to share my work with the community!