ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Validation callbacks into Models

January 24, 2008 5:48pm

Subscribe [6]
  • #1 / Jan 24, 2008 5:48pm

    wiredesignz

    2882 posts

    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:

    // 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:

    $rules['username'] => ‘trim|required|callback_users_model->is_unique[username]’;
  • #2 / Jan 26, 2008 3:00am

    xwero

    4145 posts

    It’s great idea but i think it should be worked out some more. I think following format offers more flexibility.

    $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

    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

    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 / Jan 28, 2008 3:23am

    xwero

    4145 posts

    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 / Jan 28, 2008 3:58am

    wiredesignz

    2882 posts

    :coolsmile:

  • #5 / Feb 02, 2008 5:12am

    dawnerd

    53 posts

    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 / Feb 02, 2008 10:34am

    Chris Newton

    440 posts

    I use callbacks with underscores all the time. You just have to call them like this; callback__myfunction

  • #7 / Feb 02, 2008 2:10pm

    dawnerd

    53 posts

    Strange, I tried that and it failed. I’ll give it another shot though.

  • #8 / Feb 02, 2008 10:54pm

    Chris Newton

    440 posts

    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 / Apr 23, 2008 2:59am

    beemr

    160 posts

    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 / Apr 23, 2008 3:08am

    beemr

    160 posts

    @mahuti
    Whoops.  I didn’t realize your post was off-topic.  Anyhoo, it’s still a great library to bring into ActiveRecord_Class_Mod.

  • #11 / Apr 23, 2008 3:47am

    wiredesignz

    2882 posts

    A nice addition might be for MY_Validation to test isset($parent) and then use $parent =& get_instance() if not valid, so you don’t have to pass $CI.

    First altering run(&$parent = NULL) to prevent errors of course.

    If someone would like to test for me, I will add it to the wiki if it’s successful.

  • #12 / Apr 23, 2008 5:32am

    beemr

    160 posts

    so you don’t have to pass $CI.

    Actually, I don’t think you have to pass anything.  Since this library is an extension of CI_Validation, there is already a CI instance, namely $this->CI.  I just now replaced $parent with $this->CI and removed the run() argument, and it all worked from my library.  I only use this as an extension of the ActiveRecord_Class_Mod, so if you can verify that controller calls will work, I think this extension just got DRY-er.

  • #13 / Apr 23, 2008 7:55am

    wiredesignz

    2882 posts

    Yes but the $parent argument allows MY_Validation to work with Modular Extension Models also. Thanks for testing beemr 😉

  • #14 / Apr 23, 2008 8:27am

    beemr

    160 posts

    OK.  Not knowing how this would affect Modular Extension Models, I did just what you asked and the function was successful from my library whether I passed run($this->CI) or not.

    The new run() opening looks like this:

    function run(&$parent = NULL)
        {
            if (!isset($parent)) $parent =& get_instance();

    Hope that helps.

    P.S. Any good links on the merits of an HMVC vs. standard MVC?

  • #15 / Apr 23, 2008 6:16pm

    wiredesignz

    2882 posts

    Thanks beemr, I will update the wiki to use this. 😉

    This original description of the MVC design pattern might interest you.
    How to use Model-View-Controller (MVC)

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases