00001 <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 class CI_Form_validation {
00028
00029 var $CI;
00030 var $_field_data = array();
00031 var $_config_rules = array();
00032 var $_error_array = array();
00033 var $_error_messages = array();
00034 var $_error_prefix = '<p>';
00035 var $_error_suffix = '</p>';
00036 var $error_string = '';
00037 var $_safe_form_data = FALSE;
00038
00039
00040
00041
00042
00043
00044 function CI_Form_validation($rules = array())
00045 {
00046 $this->CI =& get_instance();
00047
00048
00049 $this->_config_rules = $rules;
00050
00051
00052 $this->CI->load->helper('form');
00053
00054
00055 if (function_exists('mb_internal_encoding'))
00056 {
00057 mb_internal_encoding($this->CI->config->item('charset'));
00058 }
00059
00060 log_message('debug', "Validation Class Initialized");
00061 }
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 function set_rules($field, $label = '', $rules = '')
00077 {
00078
00079 if (count($_POST) == 0)
00080 {
00081 return;
00082 }
00083
00084
00085
00086 if (is_array($field))
00087 {
00088 foreach ($field as $row)
00089 {
00090
00091 if ( ! isset($row['field']) OR ! isset($row['rules']))
00092 {
00093 continue;
00094 }
00095
00096
00097 $label = ( ! isset($row['label'])) ? $row['field'] : $row['label'];
00098
00099
00100 $this->set_rules($row['field'], $label, $row['rules']);
00101 }
00102 return;
00103 }
00104
00105
00106 if ( ! is_string($field) OR ! is_string($rules) OR $field == '')
00107 {
00108 return;
00109 }
00110
00111
00112 $label = ($label == '') ? $field : $label;
00113
00114
00115
00116
00117 if (strpos($field, '[') !== FALSE AND preg_match_all('/\[(.*?)\]/', $field, $matches))
00118 {
00119
00120
00121 $x = explode('[', $field);
00122 $indexes[] = current($x);
00123
00124 for ($i = 0; $i < count($matches['0']); $i++)
00125 {
00126 if ($matches['1'][$i] != '')
00127 {
00128 $indexes[] = $matches['1'][$i];
00129 }
00130 }
00131
00132 $is_array = TRUE;
00133 }
00134 else
00135 {
00136 $indexes = array();
00137 $is_array = FALSE;
00138 }
00139
00140
00141 $this->_field_data[$field] = array(
00142 'field' => $field,
00143 'label' => $label,
00144 'rules' => $rules,
00145 'is_array' => $is_array,
00146 'keys' => $indexes,
00147 'postdata' => NULL,
00148 'error' => ''
00149 );
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 function set_message($lang, $val = '')
00166 {
00167 if ( ! is_array($lang))
00168 {
00169 $lang = array($lang => $val);
00170 }
00171
00172 $this->_error_messages = array_merge($this->_error_messages, $lang);
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 function set_error_delimiters($prefix = '<p>', $suffix = '</p>')
00188 {
00189 $this->_error_prefix = $prefix;
00190 $this->_error_suffix = $suffix;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 function error($field = '', $prefix = '', $suffix = '')
00205 {
00206 if ( ! isset($this->_field_data[$field]['error']) OR $this->_field_data[$field]['error'] == '')
00207 {
00208 return '';
00209 }
00210
00211 if ($prefix == '')
00212 {
00213 $prefix = $this->_error_prefix;
00214 }
00215
00216 if ($suffix == '')
00217 {
00218 $suffix = $this->_error_suffix;
00219 }
00220
00221 return $prefix.$this->_field_data[$field]['error'].$suffix;
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 function error_string($prefix = '', $suffix = '')
00237 {
00238
00239 if (count($this->_error_array) === 0)
00240 {
00241 return '';
00242 }
00243
00244 if ($prefix == '')
00245 {
00246 $prefix = $this->_error_prefix;
00247 }
00248
00249 if ($suffix == '')
00250 {
00251 $suffix = $this->_error_suffix;
00252 }
00253
00254
00255 $str = '';
00256 foreach ($this->_error_array as $val)
00257 {
00258 if ($val != '')
00259 {
00260 $str .= $prefix.$val.$suffix."\n";
00261 }
00262 }
00263
00264 return $str;
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 function run($group = '')
00278 {
00279
00280 if (count($_POST) == 0)
00281 {
00282 return FALSE;
00283 }
00284
00285
00286
00287 if (count($this->_field_data) == 0)
00288 {
00289
00290 if (count($this->_config_rules) == 0)
00291 {
00292 return FALSE;
00293 }
00294
00295
00296 $uri = ($group == '') ? trim($this->CI->uri->ruri_string(), '/') : $group;
00297
00298 if ($uri != '' AND isset($this->_config_rules[$uri]))
00299 {
00300 $this->set_rules($this->_config_rules[$uri]);
00301 }
00302 else
00303 {
00304 $this->set_rules($this->_config_rules);
00305 }
00306
00307
00308 if (count($this->_field_data) == 0)
00309 {
00310 log_message('debug', "Unable to find validation rules");
00311 return FALSE;
00312 }
00313 }
00314
00315
00316 $this->CI->lang->load('form_validation');
00317
00318
00319
00320 foreach ($this->_field_data as $field => $row)
00321 {
00322
00323
00324
00325 if ($row['is_array'] == TRUE)
00326 {
00327 $this->_field_data[$field]['postdata'] = $this->_reduce_array($_POST, $row['keys']);
00328 }
00329 else
00330 {
00331 if (isset($_POST[$field]) AND $_POST[$field] != "")
00332 {
00333 $this->_field_data[$field]['postdata'] = $_POST[$field];
00334 }
00335 }
00336
00337 $this->_execute($row, explode('|', $row['rules']), $this->_field_data[$field]['postdata']);
00338 }
00339
00340
00341 $total_errors = count($this->_error_array);
00342
00343 if ($total_errors > 0)
00344 {
00345 $this->_safe_form_data = TRUE;
00346 }
00347
00348
00349 $this->_reset_post_array();
00350
00351
00352 if ($total_errors == 0)
00353 {
00354 return TRUE;
00355 }
00356
00357
00358 return FALSE;
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 function _reduce_array($array, $keys, $i = 0)
00373 {
00374 if (is_array($array))
00375 {
00376 if (isset($keys[$i]))
00377 {
00378 if (isset($array[$keys[$i]]))
00379 {
00380 $array = $this->_reduce_array($array[$keys[$i]], $keys, ($i+1));
00381 }
00382 else
00383 {
00384 return NULL;
00385 }
00386 }
00387 else
00388 {
00389 return $array;
00390 }
00391 }
00392
00393 return $array;
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 function _reset_post_array()
00405 {
00406 foreach ($this->_field_data as $field => $row)
00407 {
00408 if ( ! is_null($row['postdata']))
00409 {
00410 if ($row['is_array'] == FALSE)
00411 {
00412 if (isset($_POST[$row['field']]))
00413 {
00414 $_POST[$row['field']] = $this->prep_for_form($row['postdata']);
00415 }
00416 }
00417 else
00418 {
00419 $post = '$_POST["';
00420
00421 if (count($row['keys']) == 1)
00422 {
00423 $post .= current($row['keys']);
00424 $post .= '"]';
00425 }
00426 else
00427 {
00428 $i = 0;
00429 foreach ($row['keys'] as $val)
00430 {
00431 if ($i == 0)
00432 {
00433 $post .= $val.'"]';
00434 $i++;
00435 continue;
00436 }
00437
00438 $post .= '["'.$val.'"]';
00439 }
00440 }
00441
00442 if (is_array($row['postdata']))
00443 {
00444 $array = array();
00445 foreach ($row['postdata'] as $k => $v)
00446 {
00447 $array[$k] = $this->prep_for_form($v);
00448 }
00449
00450 $post .= ' = $array;';
00451 }
00452 else
00453 {
00454 $post .= ' = "'.$this->prep_for_form($row['postdata']).'";';
00455 }
00456
00457 eval($post);
00458 }
00459 }
00460 }
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 function _execute($row, $rules, $postdata = NULL, $cycles = 0)
00476 {
00477
00478 if (is_array($postdata))
00479 {
00480 foreach ($postdata as $key => $val)
00481 {
00482 $this->_execute($row, $rules, $val, $cycles);
00483 $cycles++;
00484 }
00485
00486 return;
00487 }
00488
00489
00490
00491
00492 $callback = FALSE;
00493 if ( ! in_array('required', $rules) AND is_null($postdata))
00494 {
00495
00496 if (preg_match("/(callback_\w+)/", implode(' ', $rules), $match))
00497 {
00498 $callback = TRUE;
00499 $rules = (array('1' => $match[1]));
00500 }
00501 else
00502 {
00503 return;
00504 }
00505 }
00506
00507
00508
00509
00510 if (is_null($postdata) AND $callback == FALSE)
00511 {
00512 if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))
00513 {
00514
00515 $type = (in_array('required', $rules)) ? 'required' : 'isset';
00516
00517 if ( ! isset($this->_error_messages[$type]))
00518 {
00519 if (FALSE === ($line = $this->CI->lang->line($type)))
00520 {
00521 $line = 'The field was not set';
00522 }
00523 }
00524 else
00525 {
00526 $line = $this->_error_messages[$type];
00527 }
00528
00529
00530 $message = sprintf($line, $this->_translate_fieldname($row['label']));
00531
00532
00533 $this->_field_data[$row['field']]['error'] = $message;
00534
00535 if ( ! isset($this->_error_array[$row['field']]))
00536 {
00537 $this->_error_array[$row['field']] = $message;
00538 }
00539 }
00540
00541 return;
00542 }
00543
00544
00545
00546
00547 foreach ($rules As $rule)
00548 {
00549 $_in_array = FALSE;
00550
00551
00552
00553 if ($row['is_array'] == TRUE AND is_array($this->_field_data[$row['field']]['postdata']))
00554 {
00555
00556
00557 if ( ! isset($this->_field_data[$row['field']]['postdata'][$cycles]))
00558 {
00559 continue;
00560 }
00561
00562 $postdata = $this->_field_data[$row['field']]['postdata'][$cycles];
00563 $_in_array = TRUE;
00564 }
00565 else
00566 {
00567 $postdata = $this->_field_data[$row['field']]['postdata'];
00568 }
00569
00570
00571
00572
00573 $callback = FALSE;
00574 if (substr($rule, 0, 9) == 'callback_')
00575 {
00576 $rule = substr($rule, 9);
00577 $callback = TRUE;
00578 }
00579
00580
00581
00582 $param = FALSE;
00583 if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))
00584 {
00585 $rule = $match[1];
00586 $param = $match[2];
00587 }
00588
00589
00590 if ($callback === TRUE)
00591 {
00592 if ( ! method_exists($this->CI, $rule))
00593 {
00594 continue;
00595 }
00596
00597
00598 $result = $this->CI->$rule($postdata, $param);
00599
00600
00601 if ($_in_array == TRUE)
00602 {
00603 $this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
00604 }
00605 else
00606 {
00607 $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
00608 }
00609
00610
00611 if ( ! in_array('required', $rules, TRUE) AND $result !== FALSE)
00612 {
00613 return;
00614 }
00615 }
00616 else
00617 {
00618 if ( ! method_exists($this, $rule))
00619 {
00620
00621
00622 if (function_exists($rule))
00623 {
00624 $result = $rule($postdata);
00625
00626 if ($_in_array == TRUE)
00627 {
00628 $this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
00629 }
00630 else
00631 {
00632 $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
00633 }
00634 }
00635
00636 continue;
00637 }
00638
00639 $result = $this->$rule($postdata, $param);
00640
00641 if ($_in_array == TRUE)
00642 {
00643 $this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
00644 }
00645 else
00646 {
00647 $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
00648 }
00649 }
00650
00651
00652 if ($result === FALSE)
00653 {
00654 if ( ! isset($this->_error_messages[$rule]))
00655 {
00656 if (FALSE === ($line = $this->CI->lang->line($rule)))
00657 {
00658 $line = 'Unable to access an error message corresponding to your field name.';
00659 }
00660 }
00661 else
00662 {
00663 $line = $this->_error_messages[$rule];
00664 }
00665
00666
00667 $message = sprintf($line, $this->_translate_fieldname($row['label']), $param);
00668
00669
00670 $this->_field_data[$row['field']]['error'] = $message;
00671
00672 if ( ! isset($this->_error_array[$row['field']]))
00673 {
00674 $this->_error_array[$row['field']] = $message;
00675 }
00676
00677 return;
00678 }
00679 }
00680 }
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691 function _translate_fieldname($fieldname)
00692 {
00693
00694
00695 if (substr($fieldname, 0, 5) == 'lang:')
00696 {
00697
00698 $line = substr($fieldname, 5);
00699
00700
00701 if (FALSE === ($fieldname = $this->CI->lang->line($line)))
00702 {
00703 return $line;
00704 }
00705 }
00706
00707 return $fieldname;
00708 }
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723 function set_value($field = '', $default = '')
00724 {
00725 if ( ! isset($this->_field_data[$field]))
00726 {
00727 return $default;
00728 }
00729
00730 return $this->_field_data[$field]['postdata'];
00731 }
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746 function set_select($field = '', $value = '', $default = FALSE)
00747 {
00748 if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))
00749 {
00750 if ($default === TRUE AND count($this->_field_data) === 0)
00751 {
00752 return ' selected="selected"';
00753 }
00754 return '';
00755 }
00756
00757 $field = $this->_field_data[$field]['postdata'];
00758
00759 if (is_array($field))
00760 {
00761 if ( ! in_array($value, $field))
00762 {
00763 return '';
00764 }
00765 }
00766 else
00767 {
00768 if (($field == '' OR $value == '') OR ($field != $value))
00769 {
00770 return '';
00771 }
00772 }
00773
00774 return ' selected="selected"';
00775 }
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790 function set_radio($field = '', $value = '', $default = FALSE)
00791 {
00792 if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))
00793 {
00794 if ($default === TRUE AND count($this->_field_data) === 0)
00795 {
00796 return ' checked="checked"';
00797 }
00798 return '';
00799 }
00800
00801 $field = $this->_field_data[$field]['postdata'];
00802
00803 if (is_array($field))
00804 {
00805 if ( ! in_array($value, $field))
00806 {
00807 return '';
00808 }
00809 }
00810 else
00811 {
00812 if (($field == '' OR $value == '') OR ($field != $value))
00813 {
00814 return '';
00815 }
00816 }
00817
00818 return ' checked="checked"';
00819 }
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834 function set_checkbox($field = '', $value = '', $default = FALSE)
00835 {
00836 if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))
00837 {
00838 if ($default === TRUE AND count($this->_field_data) === 0)
00839 {
00840 return ' checked="checked"';
00841 }
00842 return '';
00843 }
00844
00845 $field = $this->_field_data[$field]['postdata'];
00846
00847 if (is_array($field))
00848 {
00849 if ( ! in_array($value, $field))
00850 {
00851 return '';
00852 }
00853 }
00854 else
00855 {
00856 if (($field == '' OR $value == '') OR ($field != $value))
00857 {
00858 return '';
00859 }
00860 }
00861
00862 return ' checked="checked"';
00863 }
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 function required($str)
00875 {
00876 if ( ! is_array($str))
00877 {
00878 return (trim($str) == '') ? FALSE : TRUE;
00879 }
00880 else
00881 {
00882 return ( ! empty($str));
00883 }
00884 }
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896 function matches($str, $field)
00897 {
00898 if ( ! isset($_POST[$field]))
00899 {
00900 return FALSE;
00901 }
00902
00903 $field = $_POST[$field];
00904
00905 return ($str !== $field) ? FALSE : TRUE;
00906 }
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918 function min_length($str, $val)
00919 {
00920 if (preg_match("/[^0-9]/", $val))
00921 {
00922 return FALSE;
00923 }
00924
00925 if (function_exists('mb_strlen'))
00926 {
00927 return (mb_strlen($str) < $val) ? FALSE : TRUE;
00928 }
00929
00930 return (strlen($str) < $val) ? FALSE : TRUE;
00931 }
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943 function max_length($str, $val)
00944 {
00945 if (preg_match("/[^0-9]/", $val))
00946 {
00947 return FALSE;
00948 }
00949
00950 if (function_exists('mb_strlen'))
00951 {
00952 return (mb_strlen($str) > $val) ? FALSE : TRUE;
00953 }
00954
00955 return (strlen($str) > $val) ? FALSE : TRUE;
00956 }
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 function exact_length($str, $val)
00969 {
00970 if (preg_match("/[^0-9]/", $val))
00971 {
00972 return FALSE;
00973 }
00974
00975 if (function_exists('mb_strlen'))
00976 {
00977 return (mb_strlen($str) != $val) ? FALSE : TRUE;
00978 }
00979
00980 return (strlen($str) != $val) ? FALSE : TRUE;
00981 }
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992 function valid_email($str)
00993 {
00994 return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
00995 }
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006 function valid_emails($str)
01007 {
01008 if (strpos($str, ',') === FALSE)
01009 {
01010 return $this->valid_email(trim($str));
01011 }
01012
01013 foreach(explode(',', $str) as $email)
01014 {
01015 if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)
01016 {
01017 return FALSE;
01018 }
01019 }
01020
01021 return TRUE;
01022 }
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033 function valid_ip($ip)
01034 {
01035 return $this->CI->input->valid_ip($ip);
01036 }
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047 function alpha($str)
01048 {
01049 return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE;
01050 }
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061 function alpha_numeric($str)
01062 {
01063 return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE;
01064 }
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075 function alpha_dash($str)
01076 {
01077 return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;
01078 }
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089 function numeric($str)
01090 {
01091 return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);
01092
01093 }
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104 function is_numeric($str)
01105 {
01106 return ( ! is_numeric($str)) ? FALSE : TRUE;
01107 }
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118 function integer($str)
01119 {
01120 return (bool)preg_match( '/^[\-+]?[0-9]+$/', $str);
01121 }
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132 function is_natural($str)
01133 {
01134 return (bool)preg_match( '/^[0-9]+$/', $str);
01135 }
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146 function is_natural_no_zero($str)
01147 {
01148 if ( ! preg_match( '/^[0-9]+$/', $str))
01149 {
01150 return FALSE;
01151 }
01152
01153 if ($str == 0)
01154 {
01155 return FALSE;
01156 }
01157
01158 return TRUE;
01159 }
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173 function valid_base64($str)
01174 {
01175 return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str);
01176 }
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190 function prep_for_form($data = '')
01191 {
01192 if (is_array($data))
01193 {
01194 foreach ($data as $key => $val)
01195 {
01196 $data[$key] = $this->prep_for_form($val);
01197 }
01198
01199 return $data;
01200 }
01201
01202 if ($this->_safe_form_data == FALSE OR $data === '')
01203 {
01204 return $data;
01205 }
01206
01207 return str_replace(array("'", '"', '<', '>'), array("'", """, '<', '>'), stripslashes($data));
01208 }
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219 function prep_url($str = '')
01220 {
01221 if ($str == 'http://' OR $str == '')
01222 {
01223 return '';
01224 }
01225
01226 if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')
01227 {
01228 $str = 'http://'.$str;
01229 }
01230
01231 return $str;
01232 }
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243 function strip_image_tags($str)
01244 {
01245 return $this->CI->input->strip_image_tags($str);
01246 }
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257 function xss_clean($str)
01258 {
01259 return $this->CI->input->xss_clean($str);
01260 }
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271 function encode_php_tags($str)
01272 {
01273 return str_replace(array('<?php', '<?PHP', '<?', '?>'), array('<?php', '<?PHP', '<?', '?>'), $str);
01274 }
01275
01276 }
01277
01278
01279
01280