Part of the EllisLab Network
x
 
Create New Page
 View Previous Changes    ( Last updated by wiredesignz )

MY Validation - Callbacks into Models

Category:Libraries -> Validation | Category:Libraries -> Community

Setting Up:

$this->validation->set_rules(array(
            
'username'    => 'trim|required|callback_users_model->is_unique[username]',
            
'password'    => 'trim|required|matches[confirm]',
        ));

The callback function in users_model

/**
     * Validation callback
     **/
    function is_unique($value, $field)
    
{
        $this
->validation->set_message('users_model->is_unique', "The %s {$value} is not available. Try a different username");
        return (bool)(!
$this->findBy("{$field} = '{$value}'"));
    
}


This is a more advanced version of the previous callbacks into models extension. You may pass the calling object to the Validation class. ie: $this->validation->run($this); If not it wil use the CI super object by default.

application/libraries/MY_Validation.php

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
* MY_Validation extension
*
* Allows callback functions into Module or Models
*
* Version 0.3 (c) Wiredesignz 2008-04-24
*/

class MY_Validation extends CI_Validation
{
    
function get_fields()
    
{
        
return $this->_fields;
    
}
    
    
/**
     * Run the Validator
     *
     * This function does all the work.
     *
     * @access    public
     * @return    bool
     */        
    
function run(&$parent)
    
{        
        
// Do we even have any data to process?  Hmm?
        
if (count($_POST) == 0 OR count($this->_rules) == 0)
        
{
            
return FALSE;
        
}
    
        
// Load the language file containing error messages
        
$parent->load->language('validation');
                            
        
// Cycle through the rules and test for errors
        
foreach ($this->_rules as $field => $rules)
        
{
            
//Explode out the rules!
            
$ex = explode('|', $rules);

            
// Is the field required?  If not, if the field is blank  we'll move on to the next test
            
if ( ! in_array('required', $ex, TRUE))
            
{
                
if ( ! isset($_POST[$field]) OR $_POST[$field] == '')
                
{
                    
continue;
                
}
            }
            
            
/*
             * Are we dealing with an "isset" rule?
             *
             * Before going further, we'll see if one of the rules
             * is to check whether the item is set (typically this
             * applies only to checkboxes).  If so, we'll
             * test for it here since there's not reason to go
             * further
             */
            
if ( ! isset($_POST[$field]))
            
{            
                
if (in_array('isset', $ex, TRUE) OR in_array('required', $ex))
                
{
                    
if ( ! isset($this->_error_messages['isset']))
                    
{
                        
if (FALSE === ($line = $parent->lang->line('isset')))
                        
{
                            $line
= 'The field was not set';
                        
}                            
                    }
                    
else
                    
{
                        $line
= $this->_error_messages['isset'];
                    
}
                    
                    
// Build the error message
                    
$mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
                    
$message = sprintf($line, $mfield);

                    
// Set the error variable.  Example: $this->username_error
                    
$error = $field.'_error';
                    
$this->$error = $this->_error_prefix.$message.$this->_error_suffix;
                    
$this->_error_array[] = $message;
                
}
                        
                
continue;
            
}
    
            
/*
             * Set the current field
             *
             * The various prepping functions need to know the
             * current field name so they can do this:
             *
             * $_POST[$this->_current_field] == 'bla bla';
             */
            
$this->_current_field = $field;

            
// Cycle through the rules!
            
foreach ($ex As $rule)
            
{
                
// Is the rule a callback?            
                
$callback = FALSE;
                if (
substr($rule, 0, 9) == 'callback_')
                
{
                    $rule
= substr($rule, 9);
                    
$callback = TRUE;
                
}
                
                
// Strip the parameter (if exists) from the rule
                // Rules can contain a parameter: max_length[5]
                
$param = FALSE;
                if (
preg_match("/(.*?)\[(.*?)\]/", $rule, $match))
                
{
                    $rule    
= $match[1];
                    
$param    = $match[2];
                
}

    
// Call the function that corresponds to the rule
    
if ($callback === TRUE)
    
{                    
        
/* Allows callbacks into Models */
        
        
if (list($class, $method) = split('->', $rule))
        
{
            
if ( ! method_exists($parent->$class, $method))
            
{         
                
continue;
            
}
        
            $result
= $parent->$class->$method($_POST[$field], $param);
        
}
        
else
        
{
            
if ( ! method_exists($parent, $rule))
            
{         
                
continue;
            
}
            
            $result
= $parent->$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
                
{                
                    
if ( ! method_exists($this, $rule))
                    
{
                        
/*
                         * Run the native PHP function if called for
                         *
                         * If our own wrapper function doesn't exist we see
                         * if a native PHP function does. Users can use
                         * any native PHP function call that has one param.
                         */
                        
if (function_exists($rule))
                        
{
                            $_POST[$field]
= $rule($_POST[$field]);
                            
$this->$field = $_POST[$field];
                        
}
                                            
                        
continue;
                    
}
                    
                    $result
= $this->$rule($_POST[$field], $param);
                
}
                                
                
// Did the rule test negatively?  If so, grab the error.
                
if ($result === FALSE)
                
{
                    
if ( ! isset($this->_error_messages[$rule]))
                    
{
                        
if (FALSE === ($line = $parent->lang->line($rule)))
                        
{
                            $line
= 'Unable to access an error message corresponding to your field name.';
                        
}                        
                    }
                    
else
                    
{
                        $line
= $this->_error_messages[$rule];
                    
}                

                    
// Build the error message
                    
$mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
                    
$mparam = ( ! isset($this->_fields[$param])) ? $param : $this->_fields[$param];
                    
$message = sprintf($line, $mfield, $mparam);
                    
                    
// Set the error variable.  Example: $this->username_error
                    
$error = $field.'_error';
                    
$this->$error = $this->_error_prefix.$message.$this->_error_suffix;

                    
// Add the error to the error array
                    
$this->_error_array[] = $message;                
                    
                    continue
2;
                
}                
            }
            
        }
        
        $total_errors
= count($this->_error_array);

        
/*
         * Recompile the class variables
         *
         * If any prepping functions were called the $_POST data
         * might now be different then the corresponding class
         * variables so we'll set them anew.
         */    
        
if ($total_errors > 0)
        
{
            $this
->_safe_form_data = TRUE;
        
}
        
        $this
->set_fields();

        
// Did we end up with any errors?
        
if ($total_errors == 0)
        
{
            
return TRUE;
        
}
        
        
// Generate the error string
        
foreach ($this->_error_array as $val)
        
{
            $this
->error_string .= $this->_error_prefix.$val.$this->_error_suffix."\n";
        
}

        
return FALSE;
    
}
}