Welcome Guest, Not a member yet? Register   Sign In
Use Models, Libraries and Helpers in Form Validation rules
#1

[eluser]CroNiX[/eluser]
The original idea for this came from Skunkbad in this thread, where he created a way to use models in validation rules. I simply took his concept created a single new validation rule that would allow using Models, Libraries and Helpers as well. Additionally, if your own callback rule requires parameters passed to it via square brackets, you can still use those as you originally would with the original form validation class. Please see the notes in the class for reserved characters that cannot be used as delimiters in your own rules or they will clash with CI's rule delimeters or the ones I use.

The main benefit is to be able to consolidate and separate the validation logic outside of the controller and also avoid having a huge MY_Form_Validation rule set for larger projects.

Code:
<?php
class MY_Form_validation extends CI_Form_validation
{
/**
  * Allows using CI Models, Libraries and Helpers externally for validation rules
  *
  * Use: external_callback[type.name.function] or external_callback[type.name.function[params]]
  * Type = library, model, or helper!
  * Name = name of library/model/helper
  * Function = function/method of rule
  * Params = (optional) parameters set in square brackets to pass to your callback validation function
  *
  * Note 1: When defining external callbacks, the error message must be "external_callback" and not the name of the individual function.
  * Note 2: Do not use the pipe (|) or dots(.) in extra data transmitted within brackets ([]) in your own callback functions.
  *         CI uses pipes to separate rules and this external function uses dots, so using either will break rules.
  *
  * @param String $postdata Same as param1 sent to callback functions
  * @param String $extra    Same as param2 sent to callback functions (within square brackets)
         * See: http://ellislab.com/codeigniter/user-guide/libraries/form_validation.html#callbacks
  */

public function external_callback($postdata, $extra)
{  
  //Separate out the parts we need from $extra
  list($external_type, $name, $function) = explode('.', $extra);
  $external_type = strtolower($external_type);
  
  $CI =& get_instance();
  
  //Try loading the resource!
  $CI->load->$external_type($name);
  
  // Strip the parameter (if exists) from the rule
  // Rules can contain a parameter: max_length[5]
  $param = FALSE;
  if (preg_match("/(.*?)\[(.*)\]/", $function, $match))
  {
   $function = $match[1];
   $param = $match[2];
  }
  
  //If library or model, get the method
  $result = FALSE;
  
  if(($external_type == 'library' || $external_type == 'model') && method_exists($CI->$name, $function))
  {
   $result = ( ! empty($param)) ? $CI->$name->$function($postdata, $param) : $CI->$name->$function($postdata);
  }
  //it was a helper, just use function instead...
  else if(function_exists($function))
  {
   $result = ( ! empty($param)) ? $function($postdata, $param) : $function($postdata);
  }
  
  //return the final result of the external callback back to validation
  return $result;
}
}

Use examples:
1) You have a simple rule in a model.
/application/models/test_model.php
Code:
class Test_model extends CI_Model {
  public function not_word($str)
  {
    $CI =& get_instance();
    //note we must use 'external_callback' as the error message instead of 'test_model' like you normally would
    $CI->form_validation->set_message('external_callback', 'The %s field cannot be "word".');
    return ($str != 'word');
  }
}
Validation Rule:
Code:
$this->form_validation->set_rules('field_name', 'Field Name', 'external_callback[model.test_model.not_word]');
If the person enters "word" into the field it will fail.
external_callback[model.test_model.not_word]
Type of external callback
Name of file
Rule name in file

2) Let's say our rule had additional parameters passed to it. You do it like normal in square brackets.

Code:
class Test_model extends CI_Model {
  public function not_word($str, $param)
  {
    $CI =& get_instance();
    //note we must use 'external_callback' as the error message instead of 'test_model' like you normally would
    $CI->form_validation->set_message('external_callback', 'The %s field cannot be "' . $param . '".');
    return ($str != $param);
  }
}
Validation Rule:
Code:
$this->form_validation->set_rules('field_name', 'Field Name', 'external_callback[model.test_model.not_word[Tuesday]]');
If the person enters "Tuesday" in the field it will fail.

The rest of the code is the same for Libraries and Helpers. You just use the appropriate word instead of "model" in the rules. I hope it's useful and remember skunkbad came up with the concept.

If there are any improvements or problems please post them. I haven't done extensive testing.

Note: even if you have 10 external callbacks on the same form, the error messages still show up for the correct field even though all error messages are named after 'external_callback'.


Messages In This Thread
Use Models, Libraries and Helpers in Form Validation rules - by El Forum - 12-22-2011, 11:27 AM



Theme © iAndrew 2016 - Forum software by © MyBB