CodeIgniter Forums
optimized validation for ci - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20)
+--- Forum: Archived Libraries & Helpers (https://forum.codeigniter.com/forumdisplay.php?fid=22)
+--- Thread: optimized validation for ci (/showthread.php?tid=2442)



optimized validation for ci - El Forum - 08-06-2007

[eluser]Fabian Wesner[/eluser]
Hi, this is a tutorial how to compress the validation process and how to encapsulate the rules and fieldnames! We will save around 90% of the code inside the controller with two selfmade libraries. Give it a try!

Earlier I used ci validation for my project like it is described in the user guide. My controller looked like that:
Code:
$rules['v1'] = "trim|required|max_length[3]|xss_clean";
$rules['v2'] = "trim|required|max_length[3]|xss_clean";
$rules['v3'] = "trim|required|max_length[3]|xss_clean";
$rules['v4'] = "trim|required|max_length[3]|xss_clean";
$rules['v5'] = "trim|required|max_length[3]|xss_clean";
$rules['v6'] = "trim|required|max_length[3]|xss_clean";
$rules['v7'] = "trim|required|max_length[3]|xss_clean";
$rules['v8'] = "trim|required|max_length[3]|xss_clean";
$rules['v9'] = "trim|required|max_length[3]|xss_clean";
$rules['v10'] = "trim|required|max_length[3]|xss_clean";

$this->validation->set_rules($rules);

$fields[v1']    = '...';
$fields[v2']    = '...';
$fields[v3']    = '...';
$fields[v4']    = '...';
$fields[v5']    = '...';
$fields[v6']    = '...';
$fields[v7']    = '...';
$fields[v8']    = '...';
$fields[v9']    = '...';
$fields[v10']    = '...';

$this->validation->set_fields($fields);

if ($this->validation->run() == FALSE){
//...
}else{

  $data = array(
    'v1' => $this->validation->v1;
    'v2' => $this->validation->v2;
    'v3' => $this->validation->v3;
    'v4' => $this->validation->v4;
    'v5' => $this->validation->v5;
    'v6' => $this->validation->v6;
    'v7' => $this->validation->v7;
    'v8' => $this->validation->v8;
    'v9' => $this->validation->v9;
    'v10' => $this->validation->v10;
  );
  $this->My_model->set($data);
}

So we have a lot of code with many redundant information. With a new library it will be like that:
Code:
$field_names = array ('v1','v2','v3','v4','v5','v6','v7','v8','v9','v10');
  $validated = $this->validation->validate($field_names);
  if ($validated === FALSE) {
    //...
  } else {
    $this->My_model->set($validated);
  }


To achive this, I extended the validation library. You can create a new library called MY_Validation.php and copy the code!
Code:
if (!defined('BASEPATH')) exit('No direct script access allowed');
class MY_Validation extends CI_Validation{

    function validate(array $field_names){
        $ci =& get_instance();
        $ci->load->library('Rules');

        $rules = array();
      foreach ($field_names as $field_key) {
         $rules[$field_key] = $ci->rules->getRule($field_key);
      }
      $this->set_rules($rules);
      $this->set_error_delimiters($ci->globaltext->getPrefixText(), $ci->globaltext->getSuffixText());

        $fields = array();
      foreach ($field_names as $field_key) {
         $fields[$field_key] = $ci->rules->getField($field_key);
      }

      $this->set_fields($fields);

        if($this->run() === FALSE){
           return FALSE;
        }else{
            $validatedInput = get_object_vars($this);
         $data = array ();
         foreach ($field_names as $field_name) {
            $data[$field_name] = $validatedInput[$field_name];
         }
         return $data;
        }
    }
}

Now the function validatet() makes everything. The rules and fields are capsuled in another
library called Rules. Just create a library called Rules.php and copy it. Here you can write all the rules and fieldnames for your whole project.

Code:
if (!defined('BASEPATH'))
   exit ('No direct script access allowed');

class Rules {
   function getRule($str) {
      $str = 'rule_' . $str;
      if (isset ($this-> $str)) {
         return $this-> $str;
      } else {
         return "";
      }
   }

   function getField($str) {
      $str = 'field_' . $str;
      if (isset ($this-> $str)) {
         return $this-> $str;
      } else {
         return "";
      }
   }


  $rule_v1 = "trim|required|max_length[3]|xss_clean";
  $rule_v2 = "trim|required|max_length[3]|xss_clean";
  $rule_v3 = "trim|required|max_length[3]|xss_clean";
  $rule_v4 = "trim|required|max_length[3]|xss_clean";
  $rule_v5 = "trim|required|max_length[3]|xss_clean";
  $rule_v6 = "trim|required|max_length[3]|xss_clean";
  $rule_v7 = "trim|required|max_length[3]|xss_clean";
  $rule_v8 = "trim|required|max_length[3]|xss_clean";
  $rule_v9 = "trim|required|max_length[3]|xss_clean";
  $rule_v10 = "trim|required|max_length[3]|xss_clean";

  $field_v1= '...';
  $field_v2= '...';
  $field_v3= '...';
  $field_v4= '...';
  $field_v5= '...';
  $field_v6= '...';
  $field_v7= '...';
  $field_v8= '...';
  $field_v9= '...';
  $field_v10= '...';

}



optimized validation for ci - El Forum - 08-06-2007

[eluser]Phil Sturgeon[/eluser]
Rules is an array I like to be big and noticeable. Its quite useful to see all of whats going on. If you want to reduce the code in your origional example, try something like this:

Code:
$rules['v1'] = "trim|required|max_length[3]|xss_clean";
$rules['v2'] = "trim|required|max_length[3]|xss_clean";
$rules['v3'] = "trim|required|max_length[3]|xss_clean";
$rules['v4'] = "trim|required|max_length[3]|xss_clean";
$rules['v5'] = "trim|required|max_length[3]|xss_clean";
$rules['v6'] = "trim|required|max_length[3]|xss_clean";
$rules['v7'] = "trim|required|max_length[3]|xss_clean";
$rules['v8'] = "trim|required|max_length[3]|xss_clean";
$rules['v9'] = "trim|required|max_length[3]|xss_clean";
$rules['v10'] = "trim|required|max_length[3]|xss_clean";

$this->validation->set_rules($rules);

$this->lang->load('my_language_file');

foreach(array_keys($rules) as $field):
    $fields[$field] = $this->lang->item($field);
  endforeach;

$this->validation->set_fields($fields);

if ($this->validation->run() == FALSE){
//...
}else{

  foreach(array_keys($rules) as $field):
    $data[$field] = $this->validation->$field;
  endforeach;

  $this->My_model->set($data);
}

There, aint that perdy? Put all field names in a language file, load it and the only massive array you need in this page is the $rules one! Everything else is automatically generate from language file and validation library.

Tuck the validation away in a model file for added portability and you have a smaller, easier to manage and multi-lingual set of code.