Welcome Guest, Not a member yet? Register   Sign In
Validation callbacks into Models
#1

[eluser]wiredesignz[/eluser]
I have created a Validation library modification which allows callbacks into Models.

Save the existing Validation library as MY_validation with only the original run() function in it.
Alter the class identifier to MY_ validation and extend it off CI_Validation.

Change this code appropriatley:

Code:
// Call the function that corresponds to the rule
    if ($callback === TRUE)
    {                    
        //Allows callbacks into Models
        
        if (strpos($rule, '->'))
        {
            list($class, $method) = split('->', $rule);
            
            if ( ! method_exists($this->CI->$class, $method))
            {        
                continue;
            }
        
            $result = $this->CI->$class->$method($_POST[$field], $param);
        }
        else
        {
            if ( ! method_exists($this->CI, $rule))
            {        
                continue;
            }
            
            $result = $this->CI->$rule($_POST[$field], $param);    
        }

        //Original code continues

        // If the field isn't required and we just processed a callback we'll move on...
        if ( ! in_array('required', $ex, TRUE) AND $result !== FALSE)
        {
            continue 2;
        }
    }
    else ....

my validation callback declaration then becomes:

Code:
$rules['username'] => ‘trim|required|callback_users_model->is_unique[username]’;
#2

[eluser]xwero[/eluser]
It's great idea but i think it should be worked out some more. I think following format offers more flexibility.
Code:
$rules['username'] = 'trim|required|db_check[users,is_unique,password]'
This way there is no need to change the run method. The class and method check could be in a new method and then the db_check would look like this
Code:
function db_check($str,$param)
{
    $explode = explode(',',$param)
    if(count($explode) < 2)
    {
       return false;
    }
    
    $class = $explode[0];
    $method = $explode[1];
    if(!_check_class_method($class,$method))
    {
      return false;
    }
    else
    {
        $ci =& get_instance;
        if(count($explode) > 2)
        {
             $this->ci->$class->$method($str,array_slice($explode,2));
        }
        else
        {
             $this->ci->$class->$method($str);
        }
    }
}

function _check_class_method($class,$method)
{
    if(class_exists($class.'_model'))
    {
       method_exists($method);
    }
    return false;
}
It's some rough coding. There should be error messages or at least debug messages for the additional checks.

edit : the model method
Code:
function is_unique($username,$arr)
{
   $where['user_name'] = $username;
   $where['password'] = $this->input->post($arr[0]);
   return ($this->db->where($where)->count_all_results('users') == 1)?true:false;
}
#3

[eluser]xwero[/eluser]
I've been thinking about this functionality the weekend and i think the possible combinations and the error checks are too much for a standard validation. The biggest problem with the current validation code is the very limited functionality of the rules, they only can output a boolean. Collecting the error string in the rules would help a lot.

I'm busy hacking the validation class and this is something i will add.
#4

[eluser]wiredesignz[/eluser]
:coolsmile:
#5

[eluser]dawnerd[/eluser]
Oh please implement this. I'm tired of the way callbacks are setup. Also, how come the callback can't be prefixed with an underscore, say function _check_user rather than check_user.
#6

[eluser]Chris Newton[/eluser]
I use callbacks with underscores all the time. You just have to call them like this; callback__myfunction
#7

[eluser]dawnerd[/eluser]
Strange, I tried that and it failed. I'll give it another shot though.
#8

[eluser]Chris Newton[/eluser]
The private callbacks can't be called if you're using the callbacks in libraries though. Libraries rely on the callback function to exist and be public in the calling controller.
#9

[eluser]beemr[/eluser]
I've been able to use this in my library since wiredesignz gifted it to us. I added instructions to the wiki on how a library can call it. The instructions are for the latest revision which requires that the object gets passed into it own run() call.

I'm also using the ActiveRecord_Class_Mod, so I added an example of an "is_unique" callback for use with that library. This validation enhancement makes a great complement for it.
#10

[eluser]beemr[/eluser]
@mahuti
Whoops. I didn't realize your post was off-topic. Anyhoo, it's still a great library to bring into ActiveRecord_Class_Mod.




Theme © iAndrew 2016 - Forum software by © MyBB