FILE LINK TO MY_VALIDATION.PHP v1.22: http://rapidshare.com/files/59154081/MY_Validation.php.html
(This mod is inspired from http://codeigniter.com/forums/viewthread/47350/)
(This post has been edited to reflect recent updates)
Alright, here is my first contribution to the CI community. I wish that the developers would add this modification into the future versions of the framework.
So what is this? Well, as much as I like CI’s validation class, it does have some problems. First, you are limited to a single callback function per rule. I can find no logic behind this constraint so I have fixed this. Now, you can use as many custom callbacks as your heart desires. Second, you have to put ALL your custom callbacks in the calling controller. Why does this suck? If your site has a front (user) and back (admin) end to it, both portions might require using the same custom callback. This forces you to duplicate your callback in ALL the controllers that you want to use it in. Fun fun! I have fixed this. Now, you can create a class file anywhere in your system and put callbacks in it and load it from ANY controller. Third, if you created a custom callback to check if the username+pass match exists in the database, it would cost 1 database hit. Why is this signifigant? Well, all the callback gives you is a TRUE/FALSE at the cost of 1 hit. Thus, if the validation routine returned TRUE, you would still have to requery the database to retrieve the userdata for that username+pass. Well, I have also fixed this. In my class which extends CI_Validation I have a property called $return_data. In any of my custom validation methods, if I need to perform a database query, any return data is no longer wasted because I can simply do “$this->CI->validation->return_data[] = $query_results” to save the results while still returning TRUE/FALSE for validation purposes.
To acomplish all this I had to overwrite the run() method in CI_Validation. Some people argue that I could have simply extended CI_Validation and put my custom callbacks in there. Yes, that is very true. However there is a big disadvantage to that… a site with several modules (ex., authentication, products, categories, etc) would probably require custom validation routines for each of those modules. It sure would get cumbersome and confusing having all those modules validation routines in 1 file… plus, it would inhibit sharing files amongst the CI community. Why? Well if I wanted to download someone’s authentication package, it would come with their MY_Validation.php which I would have to go through and combine with my MY_Validation.php class. This is quite a bother. Thus, having the ability to load a custom validation class located in a ‘validators’ folder in your application directory. So just make a “validators” folder in your app dir and make your validation classes.
Okay, so how do you use my package?
1. Download My_Validation.php and plop it in your libraries folder.
2. Create a validator class in your application/validators folder.
NOTE: The validator classname must be the SAME as the validator filename.
Here is an example:
<?php if (!defined('BASEPATH')) exit('No direct script access permitted.');
/**
* This is how you create a custom validation class.
* As you can see, if the database query returns a result, we store that result
* in the $data array located in the validation object
*
* Also note how this class does not extend any other class. So it is not necessary to
* extend CI_Validation or My_Validation! Just create a class and start making your
* validators!
*/
class Book_Validator{
var $CI;
function Book_Validator()
{
$this->CI =& get_instance();
}
//Checks to see if this username was already found in the database
function title_check($title)
{
$query = $this->CI->bookmodel->getBookByName($title);
if ($query->num_rows() > 0)
{
$this->CI->validation->set_data['book_validator'] = $query->result_array();
return TRUE;
}
$this->CI->validation->set_message('title_check', 'Could not find the specified book in the database!');
return FALSE;
}
}
?>
3. In your controller, create a rule and insert your validator rule (method) into it (you do not have to add “callback_” onto your method name in the rule anymore).
$rules['title']=trim|required|min_length[5]|max_length[30]|xss_clean|title_check
4. In the controller that you want to validate, right after loading CI’s validation library, simply add ‘$this->validation->add_validator(‘your_validator_filename’);’ You can send it a single validator class name, or an array of validator class names. Here is an example:
$this->load->library('validation');
$this->validation->add_validator('book_validator');
or
$this->load->library('validation');
$this->validation->add_validator(array('book_validator', 'user_validator'));
Tell me if you guys find this useful. I’d love some feedback and I hope the developers add something like this into the next version of CI because being limited to 1 callback in the controller sucks balls.
