A peek at Kohana’s new Validation library

In Kohana’s svn repository you can find the new Validation library that will come with the next release of Kohana. There are quite some changes compared to the validation library that is now available. The current library takes much from the validation in CodeIgniter albeit with some improvements. The new one has some nifty SPL stuff and is more flexible. Great difference is that it doesn’t generate your error messages, it only validates.

In a short tutorial I’ll try to guide you through some of the features.

Firstly, the library can do several things to a variable. You can add pre-filters, rules, callbacks and post-filters. Pre- and post-filters do stuff like trimming, uppercasing, lowercasing etcetera. In short, you change the field you validate. The reason that there are pre - as well as post-filters is that order sometimes matters. For example, you might want to trim a passwordfield before you run the rules on it but afterwards you want to store a hash in the database. You add ‘trim’ as a pre-filter and ’sha1′ as a post-filter, rules are run between the two.

The order of validation is first the pre-filters, then rules, callbacks and last the post-filters. Let’s see some examples.
Filters

$_POST['title']='validation library   ';
$_POST=new Validation; //if no argument is given to the 
//constructor $_POST is assumed, new Validation($_POST); 
//would have worked as well.
 
$_POST->pre_filter('trim',true); //will trim all fields in $_POST when validated
$_POST->pre_filter('ucfirst','title');
$_POST->validate();
 
echo $_POST['title']; // I can access the object as an array due to Validation extending ArrayObject, see php spl for more info
//echoes 'Validation library'

This should be pretty clear I think. I trim all fields, and capitalize the title field and then I validate the object. All filters, rules callbacks are executed on validate. You can add any callback to filters, rules and callbacks but for filters it’s necessary it takes the field as an argument and returns the filtered field.

Post filters do not differ from pre filters so no examples for those.
Rules

$_POST['email']='test@test ';
$_POST=new Validation; 
 
$_POST->add_rules('email','required',array('valid','email'); //sets the email field as required 
//and must validate as an email, the valid:email() 
//callback refers to the valid helper. 
//$_POST->add_rules('email','required',array('valid::email')); is possible in php5 as well.
$_POST->validate();
 
var_dump($_POST->errors());
//returns  
//array(1) { ["email"]=>  string(5) "email" }

You see that the email field gives an error on the validity of the email field. Since it is not empty it the required statement gives out true. The library will only return the first error it encounters for a field.

You can add any callback as a rule but it should return true or false. ‘required’, ‘matches’ and ‘length’ are native to the validation library.

Callbacks

$_POST['email']='test';
$_POST=new Validation($_POST);
$d->add_callbacks('email',array('valid','test'));
$d->validate();

I added a method test to the valid helper. The first argument passed to the callback is the Validation object. You can manipulate the object, add your own errors. This gives you some freedom to do your own exotic validation.

In all of the above mentioned cases you see that $_POST->validate(); executes the rules, filters and callbacks.
SPL
If you look at the source you’ll see that the Validation library extends ArrayObject, this is an SPL class of php and provides the library with some handy features.
You’ve already seen you can access the object using array syntax, this is SPL magic. The $_POST thus both functions as an array as well as an object. To retrieve a normal array from $_POST you can do $_POST->as_array();

Conclusion
I hope this clears things up a bit regarding the validation library. It is more powerful that the previous library although it may require some extra work when you need error messages. The SPL provides some very nice features for you to work with forms.


17 Responses to “A peek at Kohana’s new Validation library”

  1. nrm Says:

    how to set error and print in in view?!? (i don’t like this new lib).

  2. admin Says:

    $_POST->errors() has all errors, the message handling is up to you. There is a message() method which can help you as well as a load_errors() method.

    If you don’t like this library maybe you can take a look at what I wrote for myself:

    http://h1368840.stratoserver.net/2008/03/06/formationvalidation/

  3. neovive Says:

    Is this integrated into the Forge module as well?

  4. admin Says:

    Kohana’s new validation library is not integrated with the Forge module. Formation/Validation is a replacement of both Forge and the validation library in Kohana.

  5. nrm Says:

    and what about upload? hmm, i must use old validation lib which is more better ;) and ready to use.

  6. spirit Says:

    Will validation and forge libraries be updated to easily deal with forms and validation ? (display custom messages per fields, deal with upload, …) Because the validation lib is at this time really useful to validate an array but not really cool to combine with forms.

  7. admin Says:

    I don’t know if there are any plans to do what the two of you want. You can always check out http://h1368840.stratoserver.net/2008/03/06/formationvalidation/ which handles uploads and custom messages.

  8. Edemilson Lima Says:

    Shouldn’t it be:

    $some_var = new Validation($this->input->post());

    $this->input->post() already filter the data against XSS, while $_POST doesn’t.

  9. admin Says:

    It’s what you prefer.

    $_POST=new Validation ($_POST);

    is nice since you can maintain usage of $_POST. Also if xss cleaning is on $_POST is cleansed by the input library and if not you can add a xss-clean pre-filter to the variables.

  10. Edemilson Lima Says:

    I was playing with the new lib, and I could make this work:

    	// Users_Model:
    	function insert_new_user() {
    		$data = new Validation($_POST);  // $this->input->post() couldn't be used
    		$data->pre_filter('trim',TRUE);
    		$data->pre_filter('ucfirst','fullname');
    		$data->add_rules('nickname','required','length[2,32]');
    		$data->add_rules('fullname','required','length[5,96]');
    		$data->add_rules('email','required','email');  // it calls valid::email()
    		$data->add_rules('password','required','length[6,32]');
    		$data->add_rules('password_confirm','matches[password]');
    		$data->add_rules('captcha','required',array('captcha','check'));
    		if($data->validate()) {
    			echo "VALID";
    		} else {
    			echo print_r($data->errors());
    		}
    	}

    The captcha in the rules is a callback to my captcha::check() helper. But, I noticed that it must return FALSE when the field match the captcha string and TRUE when the field doesn’t match… Is this the correct behavior? My captcha::check() is:

    	function check($user_submit, $id='captcha') 
    	{
    		$session = new Session;
    		if(strtolower($user_submit) == $session->get($id)) return FALSE;
    		else return TRUE;
    	}

    As you can see, it doesn’t make much sense to return FALSE when the submitted field match the captcha string. But, the lib only validated this way…

  11. admin Says:

    It indeed should return true on a match. I’m not sure what’s wrong. You can try to add a callback for your captcha and manually use the $this->add_error() method in the callback

  12. yag Says:

    Any hints on validating fields ie. ?

    I have a form that allows users to create multiple players (sports website), and i want to validate that form using the new Validation library. Any ideas? :)

  13. yag Says:

    the input looks like
    input type=”text” name=”player[name][]“

  14. dlib Says:

    Perhaps:

    $player['name']=new Validation($player['name']);

    Now the array can be validated. The fields with [] can probably be retrieved by a numerical index. So,

    $player['name']->add_rules('1','required');
     
    To output it all:
     
    foreach($player['name'] as $field)
    {
    echo $field;
    }

    I’m not sure about this though, if it works please let me know :)

  15. Aneem Says:

    If we get some predefined error messages that we can use with this validation, life will be a bit easier… :)

  16. dlib Says:

    I don’t think that’s going to happen. One of the reasons I wrote my own validation library.

  17. aageboi Says:

    hi, I want to know how could I validate the numeric input, so when the input is not numeric it will display a error message.
    thank before.

Leave a Comment