Validation.php

Go to the documentation of this file.
00001 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
00002 /**
00003  * CodeIgniter
00004  *
00005  * An open source application development framework for PHP 4.3.2 or newer
00006  *
00007  * @package             CodeIgniter
00008  * @author              ExpressionEngine Dev Team
00009  * @copyright   Copyright (c) 2006, EllisLab, Inc.
00010  * @license             http://codeigniter.com/user_guide/license.html
00011  * @link                http://codeigniter.com
00012  * @since               Version 1.0
00013  * @filesource
00014  */
00015 
00016 // ------------------------------------------------------------------------
00017 
00018 /**
00019  * Validation Class
00020  *
00021  * @package             CodeIgniter
00022  * @subpackage  Libraries
00023  * @category    Validation
00024  * @author              ExpressionEngine Dev Team
00025  * @link                http://codeigniter.com/user_guide/libraries/validation.html
00026  */
00027 class CI_Validation {
00028         
00029         var $CI;
00030         var $error_string               = '';
00031         var $_error_array               = array();
00032         var $_rules                             = array();
00033         var $_fields                    = array();
00034         var $_error_messages    = array();
00035         var $_current_field     = '';
00036         var $_safe_form_data    = FALSE;
00037         var $_error_prefix              = '<p>';
00038         var $_error_suffix              = '</p>';
00039 
00040         
00041 
00042         /**
00043          * Constructor
00044          *
00045          */     
00046         function CI_Validation()
00047         {       
00048                 $this->CI =& get_instance();
00049                 log_message('debug', "Validation Class Initialized");
00050         }
00051         
00052         // --------------------------------------------------------------------
00053         
00054         /**
00055          * Set Fields
00056          *
00057          * This function takes an array of field names as input
00058          * and generates class variables with the same name, which will
00059          * either be blank or contain the $_POST value corresponding to it
00060          *
00061          * @access      public
00062          * @param       string
00063          * @param       string
00064          * @return      void
00065          */
00066         function set_fields($data = '', $field = '')
00067         {       
00068                 if ($data == '')
00069                 {
00070                         if (count($this->_fields) == 0)
00071                         {
00072                                 return FALSE;
00073                         }
00074                 }
00075                 else
00076                 {
00077                         if ( ! is_array($data))
00078                         {
00079                                 $data = array($data => $field);
00080                         }
00081                         
00082                         if (count($data) > 0)
00083                         {
00084                                 $this->_fields = $data;
00085                         }
00086                 }               
00087                         
00088                 foreach($this->_fields as $key => $val)
00089                 {
00090                         $this->$key = ( ! isset($_POST[$key])) ? '' : $this->prep_for_form($_POST[$key]);
00091                         
00092                         $error = $key.'_error';
00093                         if ( ! isset($this->$error))
00094                         {
00095                                 $this->$error = '';
00096                         }
00097                 }               
00098         }
00099         
00100         // --------------------------------------------------------------------
00101         
00102         /**
00103          * Set Rules
00104          *
00105          * This function takes an array of field names and validation
00106          * rules as input ad simply stores is for use later.
00107          *
00108          * @access      public
00109          * @param       mixed
00110          * @param       string
00111          * @return      void
00112          */
00113         function set_rules($data, $rules = '')
00114         {
00115                 if ( ! is_array($data))
00116                 {
00117                         if ($rules == '')
00118                                 return;
00119                                 
00120                         $data = array($data => $rules);
00121                 }
00122         
00123                 foreach ($data as $key => $val)
00124                 {
00125                         $this->_rules[$key] = $val;
00126                 }
00127         }
00128         
00129         // --------------------------------------------------------------------
00130         
00131         /**
00132          * Set Error Message
00133          *
00134          * Lets users set their own error messages on the fly.  Note:  The key
00135          * name has to match the  function name that it corresponds to.
00136          *
00137          * @access      public
00138          * @param       string
00139          * @param       string
00140          * @return      string
00141          */
00142         function set_message($lang, $val = '')
00143         {
00144                 if ( ! is_array($lang))
00145                 {
00146                         $lang = array($lang => $val);
00147                 }
00148         
00149                 $this->_error_messages = array_merge($this->_error_messages, $lang);
00150         }
00151         
00152         // --------------------------------------------------------------------
00153         
00154         /**
00155          * Set The Error Delimiter
00156          *
00157          * Permits a prefix/suffix to be added to each error message
00158          *
00159          * @access      public
00160          * @param       string
00161          * @param       string
00162          * @return      void
00163          */     
00164         function set_error_delimiters($prefix = '<p>', $suffix = '</p>')
00165         {
00166                 $this->_error_prefix = $prefix;
00167                 $this->_error_suffix = $suffix;
00168         }
00169         
00170         // --------------------------------------------------------------------
00171         
00172         /**
00173          * Run the Validator
00174          *
00175          * This function does all the work.
00176          *
00177          * @access      public
00178          * @return      bool
00179          */             
00180         function run()
00181         {
00182                 // Do we even have any data to process?  Mm?
00183                 if (count($_POST) == 0 OR count($this->_rules) == 0)
00184                 {
00185                         return FALSE;
00186                 }
00187         
00188                 // Load the language file containing error messages
00189                 $this->CI->lang->load('validation');
00190                                                         
00191                 // Cycle through the rules and test for errors
00192                 foreach ($this->_rules as $field => $rules)
00193                 {
00194                         //Explode out the rules!
00195                         $ex = explode('|', $rules);
00196 
00197                         // Is the field required?  If not, if the field is blank  we'll move on to the next test
00198                         if ( ! in_array('required', $ex, TRUE))
00199                         {
00200                                 if ( ! isset($_POST[$field]) OR $_POST[$field] == '')
00201                                 {
00202                                         continue;
00203                                 }
00204                         }
00205                         
00206                         /*
00207                          * Are we dealing with an "isset" rule?
00208                          *
00209                          * Before going further, we'll see if one of the rules
00210                          * is to check whether the item is set (typically this
00211                          * applies only to checkboxes).  If so, we'll
00212                          * test for it here since there's not reason to go
00213                          * further
00214                          */
00215                         if ( ! isset($_POST[$field]))
00216                         {                       
00217                                 if (in_array('isset', $ex, TRUE) OR in_array('required', $ex))
00218                                 {
00219                                         if ( ! isset($this->_error_messages['isset']))
00220                                         {
00221                                                 if (FALSE === ($line = $this->CI->lang->line('isset')))
00222                                                 {
00223                                                         $line = 'The field was not set';
00224                                                 }                                                       
00225                                         }
00226                                         else
00227                                         {
00228                                                 $line = $this->_error_messages['isset'];
00229                                         }
00230                                         
00231                                         // Build the error message
00232                                         $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
00233                                         $message = sprintf($line, $mfield);
00234 
00235                                         // Set the error variable.  Example: $this->username_error
00236                                         $error = $field.'_error';
00237                                         $this->$error = $this->_error_prefix.$message.$this->_error_suffix;
00238                                         $this->_error_array[] = $message;
00239                                 }
00240                                                 
00241                                 continue;
00242                         }
00243         
00244                         /*
00245                          * Set the current field
00246                          *
00247                          * The various prepping functions need to know the
00248                          * current field name so they can do this:
00249                          *
00250                          * $_POST[$this->_current_field] == 'bla bla';
00251                          */
00252                         $this->_current_field = $field;
00253 
00254                         // Cycle through the rules!
00255                         foreach ($ex As $rule)
00256                         {
00257                                 // Is the rule a callback?                      
00258                                 $callback = FALSE;
00259                                 if (substr($rule, 0, 9) == 'callback_')
00260                                 {
00261                                         $rule = substr($rule, 9);
00262                                         $callback = TRUE;
00263                                 }
00264                                 
00265                                 // Strip the parameter (if exists) from the rule
00266                                 // Rules can contain a parameter: max_length[5]
00267                                 $param = FALSE;
00268                                 if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))
00269                                 {
00270                                         $rule   = $match[1];
00271                                         $param  = $match[2];
00272                                 }
00273                                 
00274                                 // Call the function that corresponds to the rule
00275                                 if ($callback === TRUE)
00276                                 {
00277                                         if ( ! method_exists($this->CI, $rule))
00278                                         {               
00279                                                 continue;
00280                                         }
00281                                         
00282                                         $result = $this->CI->$rule($_POST[$field], $param);     
00283                                         
00284                                         // If the field isn't required and we just processed a callback we'll move on...
00285                                         if ( ! in_array('required', $ex, TRUE) AND $result !== FALSE)
00286                                         {
00287                                                 continue 2;
00288                                         }
00289                                         
00290                                 }
00291                                 else
00292                                 {                               
00293                                         if ( ! method_exists($this, $rule))
00294                                         {
00295                                                 /*
00296                                                  * Run the native PHP function if called for
00297                                                  *
00298                                                  * If our own wrapper function doesn't exist we see
00299                                                  * if a native PHP function does. Users can use
00300                                                  * any native PHP function call that has one param.
00301                                                  */
00302                                                 if (function_exists($rule))
00303                                                 {
00304                                                         $_POST[$field] = $rule($_POST[$field]);
00305                                                         $this->$field = $_POST[$field];
00306                                                 }
00307                                                                                         
00308                                                 continue;
00309                                         }
00310                                         
00311                                         $result = $this->$rule($_POST[$field], $param);
00312                                 }
00313                                                                 
00314                                 // Did the rule test negatively?  If so, grab the error.
00315                                 if ($result === FALSE)
00316                                 {
00317                                         if ( ! isset($this->_error_messages[$rule]))
00318                                         {
00319                                                 if (FALSE === ($line = $this->CI->lang->line($rule)))
00320                                                 {
00321                                                         $line = 'Unable to access an error message corresponding to your field name.';
00322                                                 }                                               
00323                                         }
00324                                         else
00325                                         {
00326                                                 $line = $this->_error_messages[$rule];
00327                                         }                               
00328 
00329                                         // Build the error message
00330                                         $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
00331                                         $mparam = ( ! isset($this->_fields[$param])) ? $param : $this->_fields[$param];
00332                                         $message = sprintf($line, $mfield, $mparam);
00333                                         
00334                                         // Set the error variable.  Example: $this->username_error
00335                                         $error = $field.'_error';
00336                                         $this->$error = $this->_error_prefix.$message.$this->_error_suffix;
00337 
00338                                         // Add the error to the error array
00339                                         $this->_error_array[] = $message;                               
00340                                         continue 2;
00341                                 }                               
00342                         }
00343                         
00344                 }
00345                 
00346                 $total_errors = count($this->_error_array);
00347 
00348                 /*
00349                  * Recompile the class variables
00350                  *
00351                  * If any prepping functions were called the $_POST data
00352                  * might now be different then the corresponding class
00353                  * variables so we'll set them anew.
00354                  */     
00355                 if ($total_errors > 0)
00356                 {
00357                         $this->_safe_form_data = TRUE;
00358                 }
00359                 
00360                 $this->set_fields();
00361 
00362                 // Did we end up with any errors?
00363                 if ($total_errors == 0)
00364                 {
00365                         return TRUE;
00366                 }
00367                 
00368                 // Generate the error string
00369                 foreach ($this->_error_array as $val)
00370                 {
00371                         $this->error_string .= $this->_error_prefix.$val.$this->_error_suffix."\n";
00372                 }
00373 
00374                 return FALSE;
00375         }
00376         
00377         // --------------------------------------------------------------------
00378         
00379         /**
00380          * Required
00381          *
00382          * @access      public
00383          * @param       string
00384          * @return      bool
00385          */
00386         function required($str)
00387         {
00388                 if ( ! is_array($str))
00389                 {
00390                         return (trim($str) == '') ? FALSE : TRUE;
00391                 }
00392                 else
00393                 {
00394                         return ( ! empty($str));
00395                 }
00396         }
00397         
00398         // --------------------------------------------------------------------
00399         
00400         /**
00401          * Match one field to another
00402          *
00403          * @access      public
00404          * @param       string
00405          * @param       field
00406          * @return      bool
00407          */
00408         function matches($str, $field)
00409         {
00410                 if ( ! isset($_POST[$field]))
00411                 {
00412                         return FALSE;
00413                 }
00414                 
00415                 return ($str !== $_POST[$field]) ? FALSE : TRUE;
00416         }
00417         
00418         // --------------------------------------------------------------------
00419         
00420         /**
00421          * Minimum Length
00422          *
00423          * @access      public
00424          * @param       string
00425          * @param       value
00426          * @return      bool
00427          */     
00428         function min_length($str, $val)
00429         {
00430                 if (preg_match("/[^0-9]/", $val))
00431                 {
00432                         return FALSE;
00433                 }
00434         
00435                 return (strlen($str) < $val) ? FALSE : TRUE;
00436         }
00437         
00438         // --------------------------------------------------------------------
00439         
00440         /**
00441          * Max Length
00442          *
00443          * @access      public
00444          * @param       string
00445          * @param       value
00446          * @return      bool
00447          */     
00448         function max_length($str, $val)
00449         {
00450                 if (preg_match("/[^0-9]/", $val))
00451                 {
00452                         return FALSE;
00453                 }
00454         
00455                 return (strlen($str) > $val) ? FALSE : TRUE;
00456         }
00457         
00458         // --------------------------------------------------------------------
00459         
00460         /**
00461          * Exact Length
00462          *
00463          * @access      public
00464          * @param       string
00465          * @param       value
00466          * @return      bool
00467          */     
00468         function exact_length($str, $val)
00469         {
00470                 if (preg_match("/[^0-9]/", $val))
00471                 {
00472                         return FALSE;
00473                 }
00474         
00475                 return (strlen($str) != $val) ? FALSE : TRUE;
00476         }
00477         
00478         // --------------------------------------------------------------------
00479         
00480         /**
00481          * Valid Email
00482          *
00483          * @access      public
00484          * @param       string
00485          * @return      bool
00486          */     
00487         function valid_email($str)
00488         {
00489                 return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
00490         }
00491 
00492         // --------------------------------------------------------------------
00493         
00494         /**
00495          * Valid Emails
00496          *
00497          * @access      public
00498          * @param       string
00499          * @return      bool
00500          */     
00501         function valid_emails($str)
00502         {
00503                 if (strpos($str, ',') === FALSE)
00504                 {
00505                         return $this->valid_email(trim($str));
00506                 }
00507                 
00508                 foreach(explode(',', $str) as $email)
00509                 {
00510                         if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)
00511                         {
00512                                 return FALSE;
00513                         }
00514                 }
00515                 
00516                 return TRUE;
00517         }
00518 
00519         // --------------------------------------------------------------------
00520         
00521         /**
00522          * Validate IP Address
00523          *
00524          * @access      public
00525          * @param       string
00526          * @return      string
00527          */
00528         function valid_ip($ip)
00529         {
00530                 return $this->CI->input->valid_ip($ip);
00531         }
00532 
00533         // --------------------------------------------------------------------
00534         
00535         /**
00536          * Alpha
00537          *
00538          * @access      public
00539          * @param       string
00540          * @return      bool
00541          */             
00542         function alpha($str)
00543         {
00544                 return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE;
00545         }
00546         
00547         // --------------------------------------------------------------------
00548         
00549         /**
00550          * Alpha-numeric
00551          *
00552          * @access      public
00553          * @param       string
00554          * @return      bool
00555          */     
00556         function alpha_numeric($str)
00557         {
00558                 return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE;
00559         }
00560         
00561         // --------------------------------------------------------------------
00562         
00563         /**
00564          * Alpha-numeric with underscores and dashes
00565          *
00566          * @access      public
00567          * @param       string
00568          * @return      bool
00569          */     
00570         function alpha_dash($str)
00571         {
00572                 return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;
00573         }
00574         
00575         // --------------------------------------------------------------------
00576         
00577         /**
00578          * Numeric
00579          *
00580          * @access      public
00581          * @param       string
00582          * @return      bool
00583          */     
00584         function numeric($str)
00585         {
00586                 return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);
00587 
00588         }
00589 
00590         // --------------------------------------------------------------------
00591 
00592     /**
00593      * Is Numeric
00594      *
00595      * @access    public
00596      * @param    string
00597      * @return    bool
00598      */
00599     function is_numeric($str)
00600     {
00601         return ( ! is_numeric($str)) ? FALSE : TRUE;
00602     } 
00603 
00604         // --------------------------------------------------------------------
00605         
00606         /**
00607          * Integer
00608          *
00609          * @access      public
00610          * @param       string
00611          * @return      bool
00612          */     
00613         function integer($str)
00614         {
00615                 return (bool)preg_match( '/^[\-+]?[0-9]+$/', $str);
00616         }
00617         
00618         // --------------------------------------------------------------------
00619         
00620         /**
00621          * Valid Base64
00622          *
00623          * Tests a string for characters outside of the Base64 alphabet
00624          * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045
00625          *
00626          * @access      public
00627          * @param       string
00628          * @return      bool
00629          */
00630         function valid_base64($str)
00631         {
00632                 return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str);
00633         }
00634 
00635         // --------------------------------------------------------------------
00636         
00637         /**
00638          * Set Select
00639          *
00640          * Enables pull-down lists to be set to the value the user
00641          * selected in the event of an error
00642          *
00643          * @access      public
00644          * @param       string
00645          * @param       string
00646          * @return      string
00647          */     
00648         function set_select($field = '', $value = '')
00649         {
00650                 if ($field == '' OR $value == '' OR  ! isset($_POST[$field]))
00651                 {
00652                         return '';
00653                 }
00654                         
00655                 if ($_POST[$field] == $value)
00656                 {
00657                         return ' selected="selected"';
00658                 }
00659         }
00660         
00661         // --------------------------------------------------------------------
00662         
00663         /**
00664          * Set Radio
00665          *
00666          * Enables radio buttons to be set to the value the user
00667          * selected in the event of an error
00668          *
00669          * @access      public
00670          * @param       string
00671          * @param       string
00672          * @return      string
00673          */     
00674         function set_radio($field = '', $value = '')
00675         {
00676                 if ($field == '' OR $value == '' OR  ! isset($_POST[$field]))
00677                 {
00678                         return '';
00679                 }
00680                         
00681                 if ($_POST[$field] == $value)
00682                 {
00683                         return ' checked="checked"';
00684                 }
00685         }
00686         
00687         // --------------------------------------------------------------------
00688         
00689         /**
00690          * Set Checkbox
00691          *
00692          * Enables checkboxes to be set to the value the user
00693          * selected in the event of an error
00694          *
00695          * @access      public
00696          * @param       string
00697          * @param       string
00698          * @return      string
00699          */     
00700         function set_checkbox($field = '', $value = '')
00701         {
00702                 if ($field == '' OR $value == '' OR  ! isset($_POST[$field]))
00703                 {
00704                         return '';
00705                 }
00706                         
00707                 if ($_POST[$field] == $value)
00708                 {
00709                         return ' checked="checked"';
00710                 }
00711         }
00712         
00713         // --------------------------------------------------------------------
00714         
00715         /**
00716          * Prep data for form
00717          *
00718          * This function allows HTML to be safely shown in a form.
00719          * Special characters are converted.
00720          *
00721          * @access      public
00722          * @param       string
00723          * @return      string
00724          */
00725         function prep_for_form($data = '')
00726         {
00727                 if (is_array($data))
00728                 {
00729                         foreach ($data as $key => $val)
00730                         {
00731                                 $data[$key] = $this->prep_for_form($val);
00732                         }
00733                         
00734                         return $data;
00735                 }
00736                 
00737                 if ($this->_safe_form_data == FALSE OR $data == '')
00738                 {
00739                         return $data;
00740                 }
00741 
00742                 return str_replace(array("'", '"', '<', '>'), array("&#39;", "&quot;", '&lt;', '&gt;'), stripslashes($data));
00743         }
00744         
00745         // --------------------------------------------------------------------
00746         
00747         /**
00748          * Prep URL
00749          *
00750          * @access      public
00751          * @param       string
00752          * @return      string
00753          */     
00754         function prep_url($str = '')
00755         {
00756                 if ($str == 'http://' OR $str == '')
00757                 {
00758                         $_POST[$this->_current_field] = '';
00759                         return;
00760                 }
00761                 
00762                 if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')
00763                 {
00764                         $str = 'http://'.$str;
00765                 }
00766                 
00767                 $_POST[$this->_current_field] = $str;
00768         }
00769         
00770         // --------------------------------------------------------------------
00771         
00772         /**
00773          * Strip Image Tags
00774          *
00775          * @access      public
00776          * @param       string
00777          * @return      string
00778          */     
00779         function strip_image_tags($str)
00780         {
00781                 $_POST[$this->_current_field] = $this->CI->input->strip_image_tags($str);
00782         }
00783         
00784         // --------------------------------------------------------------------
00785         
00786         /**
00787          * XSS Clean
00788          *
00789          * @access      public
00790          * @param       string
00791          * @return      string
00792          */     
00793         function xss_clean($str)
00794         {
00795                 $_POST[$this->_current_field] = $this->CI->input->xss_clean($str);
00796         }
00797         
00798         // --------------------------------------------------------------------
00799         
00800         /**
00801          * Convert PHP tags to entities
00802          *
00803          * @access      public
00804          * @param       string
00805          * @return      string
00806          */     
00807         function encode_php_tags($str)
00808         {
00809                 $_POST[$this->_current_field] = str_replace(array('<?php', '<?PHP', '<?', '?>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
00810         }
00811 
00812 }
00813 // END Validation Class
00814 
00815 /* End of file Validation.php */
00816 /* Location: ./system/libraries/Validation.php */