cfc02eda9b30c32395a981a90146555c4b8636bd
[living-lab-site.git] / system / libraries / Form_validation.php
1 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2 /**
3  * CodeIgniter
4  *
5  * An open source application development framework for PHP 5.1.6 or newer
6  *
7  * @package             CodeIgniter
8  * @author              ExpressionEngine Dev Team
9  * @copyright   Copyright (c) 2008 - 2011, EllisLab, Inc.
10  * @license             http://codeigniter.com/user_guide/license.html
11  * @link                http://codeigniter.com
12  * @since               Version 1.0
13  * @filesource
14  */
15
16 // ------------------------------------------------------------------------
17
18 /**
19  * Form Validation Class
20  *
21  * @package             CodeIgniter
22  * @subpackage  Libraries
23  * @category    Validation
24  * @author              ExpressionEngine Dev Team
25  * @link                http://codeigniter.com/user_guide/libraries/form_validation.html
26  */
27 class CI_Form_validation {
28
29         var $CI;
30         var $_field_data                        = array();
31         var $_config_rules                      = array();
32         var $_error_array                       = array();
33         var $_error_messages            = array();
34         var $_error_prefix                      = '<p>';
35         var $_error_suffix                      = '</p>';
36         var $error_string                       = '';
37         var $_safe_form_data            = FALSE;
38
39
40         /**
41          * Constructor
42          */
43         public function __construct($rules = array())
44         {
45                 $this->CI =& get_instance();
46
47                 // Validation rules can be stored in a config file.
48                 $this->_config_rules = $rules;
49
50                 // Automatically load the form helper
51                 $this->CI->load->helper('form');
52
53                 // Set the character encoding in MB.
54                 if (function_exists('mb_internal_encoding'))
55                 {
56                         mb_internal_encoding($this->CI->config->item('charset'));
57                 }
58
59                 log_message('debug', "Form Validation Class Initialized");
60         }
61
62         // --------------------------------------------------------------------
63
64         /**
65          * Set Rules
66          *
67          * This function takes an array of field names and validation
68          * rules as input, validates the info, and stores it
69          *
70          * @access      public
71          * @param       mixed
72          * @param       string
73          * @return      void
74          */
75         function set_rules($field, $label = '', $rules = '')
76         {
77                 // No reason to set rules if we have no POST data
78                 if (count($_POST) == 0)
79                 {
80                         return $this;
81                 }
82
83                 // If an array was passed via the first parameter instead of indidual string
84                 // values we cycle through it and recursively call this function.
85                 if (is_array($field))
86                 {
87                         foreach ($field as $row)
88                         {
89                                 // Houston, we have a problem...
90                                 if ( ! isset($row['field']) OR ! isset($row['rules']))
91                                 {
92                                         continue;
93                                 }
94
95                                 // If the field label wasn't passed we use the field name
96                                 $label = ( ! isset($row['label'])) ? $row['field'] : $row['label'];
97
98                                 // Here we go!
99                                 $this->set_rules($row['field'], $label, $row['rules']);
100                         }
101                         return $this;
102                 }
103
104                 // No fields? Nothing to do...
105                 if ( ! is_string($field) OR  ! is_string($rules) OR $field == '')
106                 {
107                         return $this;
108                 }
109
110                 // If the field label wasn't passed we use the field name
111                 $label = ($label == '') ? $field : $label;
112
113                 // Is the field name an array?  We test for the existence of a bracket "[" in
114                 // the field name to determine this.  If it is an array, we break it apart
115                 // into its components so that we can fetch the corresponding POST data later
116                 if (strpos($field, '[') !== FALSE AND preg_match_all('/\[(.*?)\]/', $field, $matches))
117                 {
118                         // Note: Due to a bug in current() that affects some versions
119                         // of PHP we can not pass function call directly into it
120                         $x = explode('[', $field);
121                         $indexes[] = current($x);
122
123                         for ($i = 0; $i < count($matches['0']); $i++)
124                         {
125                                 if ($matches['1'][$i] != '')
126                                 {
127                                         $indexes[] = $matches['1'][$i];
128                                 }
129                         }
130
131                         $is_array = TRUE;
132                 }
133                 else
134                 {
135                         $indexes        = array();
136                         $is_array       = FALSE;
137                 }
138
139                 // Build our master array
140                 $this->_field_data[$field] = array(
141                         'field'                         => $field,
142                         'label'                         => $label,
143                         'rules'                         => $rules,
144                         'is_array'                      => $is_array,
145                         'keys'                          => $indexes,
146                         'postdata'                      => NULL,
147                         'error'                         => ''
148                 );
149
150                 return $this;
151         }
152
153         // --------------------------------------------------------------------
154
155         /**
156          * Set Error Message
157          *
158          * Lets users set their own error messages on the fly.  Note:  The key
159          * name has to match the  function name that it corresponds to.
160          *
161          * @access      public
162          * @param       string
163          * @param       string
164          * @return      string
165          */
166         function set_message($lang, $val = '')
167         {
168                 if ( ! is_array($lang))
169                 {
170                         $lang = array($lang => $val);
171                 }
172
173                 $this->_error_messages = array_merge($this->_error_messages, $lang);
174
175                 return $this;
176         }
177
178         // --------------------------------------------------------------------
179
180         /**
181          * Set The Error Delimiter
182          *
183          * Permits a prefix/suffix to be added to each error message
184          *
185          * @access      public
186          * @param       string
187          * @param       string
188          * @return      void
189          */
190         function set_error_delimiters($prefix = '<p>', $suffix = '</p>')
191         {
192                 $this->_error_prefix = $prefix;
193                 $this->_error_suffix = $suffix;
194
195                 return $this;
196         }
197
198         // --------------------------------------------------------------------
199
200         /**
201          * Get Error Message
202          *
203          * Gets the error message associated with a particular field
204          *
205          * @access      public
206          * @param       string  the field name
207          * @return      void
208          */
209         function error($field = '', $prefix = '', $suffix = '')
210         {
211                 if ( ! isset($this->_field_data[$field]['error']) OR $this->_field_data[$field]['error'] == '')
212                 {
213                         return '';
214                 }
215
216                 if ($prefix == '')
217                 {
218                         $prefix = $this->_error_prefix;
219                 }
220
221                 if ($suffix == '')
222                 {
223                         $suffix = $this->_error_suffix;
224                 }
225
226                 return $prefix.$this->_field_data[$field]['error'].$suffix;
227         }
228
229         // --------------------------------------------------------------------
230
231         /**
232          * Error String
233          *
234          * Returns the error messages as a string, wrapped in the error delimiters
235          *
236          * @access      public
237          * @param       string
238          * @param       string
239          * @return      str
240          */
241         function error_string($prefix = '', $suffix = '')
242         {
243                 // No errrors, validation passes!
244                 if (count($this->_error_array) === 0)
245                 {
246                         return '';
247                 }
248
249                 if ($prefix == '')
250                 {
251                         $prefix = $this->_error_prefix;
252                 }
253
254                 if ($suffix == '')
255                 {
256                         $suffix = $this->_error_suffix;
257                 }
258
259                 // Generate the error string
260                 $str = '';
261                 foreach ($this->_error_array as $val)
262                 {
263                         if ($val != '')
264                         {
265                                 $str .= $prefix.$val.$suffix."\n";
266                         }
267                 }
268
269                 return $str;
270         }
271
272         // --------------------------------------------------------------------
273
274         /**
275          * Run the Validator
276          *
277          * This function does all the work.
278          *
279          * @access      public
280          * @return      bool
281          */
282         function run($group = '')
283         {
284                 // Do we even have any data to process?  Mm?
285                 if (count($_POST) == 0)
286                 {
287                         return FALSE;
288                 }
289
290                 // Does the _field_data array containing the validation rules exist?
291                 // If not, we look to see if they were assigned via a config file
292                 if (count($this->_field_data) == 0)
293                 {
294                         // No validation rules?  We're done...
295                         if (count($this->_config_rules) == 0)
296                         {
297                                 return FALSE;
298                         }
299
300                         // Is there a validation rule for the particular URI being accessed?
301                         $uri = ($group == '') ? trim($this->CI->uri->ruri_string(), '/') : $group;
302
303                         if ($uri != '' AND isset($this->_config_rules[$uri]))
304                         {
305                                 $this->set_rules($this->_config_rules[$uri]);
306                         }
307                         else
308                         {
309                                 $this->set_rules($this->_config_rules);
310                         }
311
312                         // We're we able to set the rules correctly?
313                         if (count($this->_field_data) == 0)
314                         {
315                                 log_message('debug', "Unable to find validation rules");
316                                 return FALSE;
317                         }
318                 }
319
320                 // Load the language file containing error messages
321                 $this->CI->lang->load('form_validation');
322
323                 // Cycle through the rules for each field, match the
324                 // corresponding $_POST item and test for errors
325                 foreach ($this->_field_data as $field => $row)
326                 {
327                         // Fetch the data from the corresponding $_POST array and cache it in the _field_data array.
328                         // Depending on whether the field name is an array or a string will determine where we get it from.
329
330                         if ($row['is_array'] == TRUE)
331                         {
332                                 $this->_field_data[$field]['postdata'] = $this->_reduce_array($_POST, $row['keys']);
333                         }
334                         else
335                         {
336                                 if (isset($_POST[$field]) AND $_POST[$field] != "")
337                                 {
338                                         $this->_field_data[$field]['postdata'] = $_POST[$field];
339                                 }
340                         }
341
342                         $this->_execute($row, explode('|', $row['rules']), $this->_field_data[$field]['postdata']);
343                 }
344
345                 // Did we end up with any errors?
346                 $total_errors = count($this->_error_array);
347
348                 if ($total_errors > 0)
349                 {
350                         $this->_safe_form_data = TRUE;
351                 }
352
353                 // Now we need to re-set the POST data with the new, processed data
354                 $this->_reset_post_array();
355
356                 // No errors, validation passes!
357                 if ($total_errors == 0)
358                 {
359                         return TRUE;
360                 }
361
362                 // Validation fails
363                 return FALSE;
364         }
365
366         // --------------------------------------------------------------------
367
368         /**
369          * Traverse a multidimensional $_POST array index until the data is found
370          *
371          * @access      private
372          * @param       array
373          * @param       array
374          * @param       integer
375          * @return      mixed
376          */
377         function _reduce_array($array, $keys, $i = 0)
378         {
379                 if (is_array($array))
380                 {
381                         if (isset($keys[$i]))
382                         {
383                                 if (isset($array[$keys[$i]]))
384                                 {
385                                         $array = $this->_reduce_array($array[$keys[$i]], $keys, ($i+1));
386                                 }
387                                 else
388                                 {
389                                         return NULL;
390                                 }
391                         }
392                         else
393                         {
394                                 return $array;
395                         }
396                 }
397
398                 return $array;
399         }
400
401         // --------------------------------------------------------------------
402
403         /**
404          * Re-populate the _POST array with our finalized and processed data
405          *
406          * @access      private
407          * @return      null
408          */
409         function _reset_post_array()
410         {
411                 foreach ($this->_field_data as $field => $row)
412                 {
413                         if ( ! is_null($row['postdata']))
414                         {
415                                 if ($row['is_array'] == FALSE)
416                                 {
417                                         if (isset($_POST[$row['field']]))
418                                         {
419                                                 $_POST[$row['field']] = $this->prep_for_form($row['postdata']);
420                                         }
421                                 }
422                                 else
423                                 {
424                                         // start with a reference
425                                         $post_ref =& $_POST;
426
427                                         // before we assign values, make a reference to the right POST key
428                                         if (count($row['keys']) == 1)
429                                         {
430                                                 $post_ref =& $post_ref[current($row['keys'])];
431                                         }
432                                         else
433                                         {
434                                                 foreach ($row['keys'] as $val)
435                                                 {
436                                                         $post_ref =& $post_ref[$val];
437                                                 }
438                                         }
439
440                                         if (is_array($row['postdata']))
441                                         {
442                                                 $array = array();
443                                                 foreach ($row['postdata'] as $k => $v)
444                                                 {
445                                                         $array[$k] = $this->prep_for_form($v);
446                                                 }
447
448                                                 $post_ref = $array;
449                                         }
450                                         else
451                                         {
452                                                 $post_ref = $this->prep_for_form($row['postdata']);
453                                         }
454                                 }
455                         }
456                 }
457         }
458
459         // --------------------------------------------------------------------
460
461         /**
462          * Executes the Validation routines
463          *
464          * @access      private
465          * @param       array
466          * @param       array
467          * @param       mixed
468          * @param       integer
469          * @return      mixed
470          */
471         function _execute($row, $rules, $postdata = NULL, $cycles = 0)
472         {
473                 // If the $_POST data is an array we will run a recursive call
474                 if (is_array($postdata))
475                 {
476                         foreach ($postdata as $key => $val)
477                         {
478                                 $this->_execute($row, $rules, $val, $cycles);
479                                 $cycles++;
480                         }
481
482                         return;
483                 }
484
485                 // --------------------------------------------------------------------
486
487                 // If the field is blank, but NOT required, no further tests are necessary
488                 $callback = FALSE;
489                 if ( ! in_array('required', $rules) AND is_null($postdata))
490                 {
491                         // Before we bail out, does the rule contain a callback?
492                         if (preg_match("/(callback_\w+)/", implode(' ', $rules), $match))
493                         {
494                                 $callback = TRUE;
495                                 $rules = (array('1' => $match[1]));
496                         }
497                         else
498                         {
499                                 return;
500                         }
501                 }
502
503                 // --------------------------------------------------------------------
504
505                 // Isset Test. Typically this rule will only apply to checkboxes.
506                 if (is_null($postdata) AND $callback == FALSE)
507                 {
508                         if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))
509                         {
510                                 // Set the message type
511                                 $type = (in_array('required', $rules)) ? 'required' : 'isset';
512
513                                 if ( ! isset($this->_error_messages[$type]))
514                                 {
515                                         if (FALSE === ($line = $this->CI->lang->line($type)))
516                                         {
517                                                 $line = 'The field was not set';
518                                         }
519                                 }
520                                 else
521                                 {
522                                         $line = $this->_error_messages[$type];
523                                 }
524
525                                 // Build the error message
526                                 $message = sprintf($line, $this->_translate_fieldname($row['label']));
527
528                                 // Save the error message
529                                 $this->_field_data[$row['field']]['error'] = $message;
530
531                                 if ( ! isset($this->_error_array[$row['field']]))
532                                 {
533                                         $this->_error_array[$row['field']] = $message;
534                                 }
535                         }
536
537                         return;
538                 }
539
540                 // --------------------------------------------------------------------
541
542                 // Cycle through each rule and run it
543                 foreach ($rules As $rule)
544                 {
545                         $_in_array = FALSE;
546
547                         // We set the $postdata variable with the current data in our master array so that
548                         // each cycle of the loop is dealing with the processed data from the last cycle
549                         if ($row['is_array'] == TRUE AND is_array($this->_field_data[$row['field']]['postdata']))
550                         {
551                                 // We shouldn't need this safety, but just in case there isn't an array index
552                                 // associated with this cycle we'll bail out
553                                 if ( ! isset($this->_field_data[$row['field']]['postdata'][$cycles]))
554                                 {
555                                         continue;
556                                 }
557
558                                 $postdata = $this->_field_data[$row['field']]['postdata'][$cycles];
559                                 $_in_array = TRUE;
560                         }
561                         else
562                         {
563                                 $postdata = $this->_field_data[$row['field']]['postdata'];
564                         }
565
566                         // --------------------------------------------------------------------
567
568                         // Is the rule a callback?
569                         $callback = FALSE;
570                         if (substr($rule, 0, 9) == 'callback_')
571                         {
572                                 $rule = substr($rule, 9);
573                                 $callback = TRUE;
574                         }
575
576                         // Strip the parameter (if exists) from the rule
577                         // Rules can contain a parameter: max_length[5]
578                         $param = FALSE;
579                         if (preg_match("/(.*?)\[(.*)\]/", $rule, $match))
580                         {
581                                 $rule   = $match[1];
582                                 $param  = $match[2];
583                         }
584
585                         // Call the function that corresponds to the rule
586                         if ($callback === TRUE)
587                         {
588                                 if ( ! method_exists($this->CI, $rule))
589                                 {
590                                         continue;
591                                 }
592
593                                 // Run the function and grab the result
594                                 $result = $this->CI->$rule($postdata, $param);
595
596                                 // Re-assign the result to the master data array
597                                 if ($_in_array == TRUE)
598                                 {
599                                         $this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
600                                 }
601                                 else
602                                 {
603                                         $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
604                                 }
605
606                                 // If the field isn't required and we just processed a callback we'll move on...
607                                 if ( ! in_array('required', $rules, TRUE) AND $result !== FALSE)
608                                 {
609                                         continue;
610                                 }
611                         }
612                         else
613                         {
614                                 if ( ! method_exists($this, $rule))
615                                 {
616                                         // If our own wrapper function doesn't exist we see if a native PHP function does.
617                                         // Users can use any native PHP function call that has one param.
618                                         if (function_exists($rule))
619                                         {
620                                                 $result = $rule($postdata);
621
622                                                 if ($_in_array == TRUE)
623                                                 {
624                                                         $this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
625                                                 }
626                                                 else
627                                                 {
628                                                         $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
629                                                 }
630                                         }
631
632                                         continue;
633                                 }
634
635                                 $result = $this->$rule($postdata, $param);
636
637                                 if ($_in_array == TRUE)
638                                 {
639                                         $this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
640                                 }
641                                 else
642                                 {
643                                         $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
644                                 }
645                         }
646
647                         // Did the rule test negatively?  If so, grab the error.
648                         if ($result === FALSE)
649                         {
650                                 if ( ! isset($this->_error_messages[$rule]))
651                                 {
652                                         if (FALSE === ($line = $this->CI->lang->line($rule)))
653                                         {
654                                                 $line = 'Unable to access an error message corresponding to your field name.';
655                                         }
656                                 }
657                                 else
658                                 {
659                                         $line = $this->_error_messages[$rule];
660                                 }
661
662                                 // Is the parameter we are inserting into the error message the name
663                                 // of another field?  If so we need to grab its "field label"
664                                 if (isset($this->_field_data[$param]) AND isset($this->_field_data[$param]['label']))
665                                 {
666                                         $param = $this->_translate_fieldname($this->_field_data[$param]['label']);
667                                 }
668
669                                 // Build the error message
670                                 $message = sprintf($line, $this->_translate_fieldname($row['label']), $param);
671
672                                 // Save the error message
673                                 $this->_field_data[$row['field']]['error'] = $message;
674
675                                 if ( ! isset($this->_error_array[$row['field']]))
676                                 {
677                                         $this->_error_array[$row['field']] = $message;
678                                 }
679
680                                 return;
681                         }
682                 }
683         }
684
685         // --------------------------------------------------------------------
686
687         /**
688          * Translate a field name
689          *
690          * @access      private
691          * @param       string  the field name
692          * @return      string
693          */
694         function _translate_fieldname($fieldname)
695         {
696                 // Do we need to translate the field name?
697                 // We look for the prefix lang: to determine this
698                 if (substr($fieldname, 0, 5) == 'lang:')
699                 {
700                         // Grab the variable
701                         $line = substr($fieldname, 5);
702
703                         // Were we able to translate the field name?  If not we use $line
704                         if (FALSE === ($fieldname = $this->CI->lang->line($line)))
705                         {
706                                 return $line;
707                         }
708                 }
709
710                 return $fieldname;
711         }
712
713         // --------------------------------------------------------------------
714
715         /**
716          * Get the value from a form
717          *
718          * Permits you to repopulate a form field with the value it was submitted
719          * with, or, if that value doesn't exist, with the default
720          *
721          * @access      public
722          * @param       string  the field name
723          * @param       string
724          * @return      void
725          */
726         function set_value($field = '', $default = '')
727         {
728                 if ( ! isset($this->_field_data[$field]))
729                 {
730                         return $default;
731                 }
732
733                 // If the data is an array output them one at a time.
734                 //     E.g: form_input('name[]', set_value('name[]');
735                 if (is_array($this->_field_data[$field]['postdata']))
736                 {
737                         return array_shift($this->_field_data[$field]['postdata']);
738                 }
739
740                 return $this->_field_data[$field]['postdata'];
741         }
742
743         // --------------------------------------------------------------------
744
745         /**
746          * Set Select
747          *
748          * Enables pull-down lists to be set to the value the user
749          * selected in the event of an error
750          *
751          * @access      public
752          * @param       string
753          * @param       string
754          * @return      string
755          */
756         function set_select($field = '', $value = '', $default = FALSE)
757         {
758                 if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))
759                 {
760                         if ($default === TRUE AND count($this->_field_data) === 0)
761                         {
762                                 return ' selected="selected"';
763                         }
764                         return '';
765                 }
766
767                 $field = $this->_field_data[$field]['postdata'];
768
769                 if (is_array($field))
770                 {
771                         if ( ! in_array($value, $field))
772                         {
773                                 return '';
774                         }
775                 }
776                 else
777                 {
778                         if (($field == '' OR $value == '') OR ($field != $value))
779                         {
780                                 return '';
781                         }
782                 }
783
784                 return ' selected="selected"';
785         }
786
787         // --------------------------------------------------------------------
788
789         /**
790          * Set Radio
791          *
792          * Enables radio buttons to be set to the value the user
793          * selected in the event of an error
794          *
795          * @access      public
796          * @param       string
797          * @param       string
798          * @return      string
799          */
800         function set_radio($field = '', $value = '', $default = FALSE)
801         {
802                 if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))
803                 {
804                         if ($default === TRUE AND count($this->_field_data) === 0)
805                         {
806                                 return ' checked="checked"';
807                         }
808                         return '';
809                 }
810
811                 $field = $this->_field_data[$field]['postdata'];
812
813                 if (is_array($field))
814                 {
815                         if ( ! in_array($value, $field))
816                         {
817                                 return '';
818                         }
819                 }
820                 else
821                 {
822                         if (($field == '' OR $value == '') OR ($field != $value))
823                         {
824                                 return '';
825                         }
826                 }
827
828                 return ' checked="checked"';
829         }
830
831         // --------------------------------------------------------------------
832
833         /**
834          * Set Checkbox
835          *
836          * Enables checkboxes to be set to the value the user
837          * selected in the event of an error
838          *
839          * @access      public
840          * @param       string
841          * @param       string
842          * @return      string
843          */
844         function set_checkbox($field = '', $value = '', $default = FALSE)
845         {
846                 if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))
847                 {
848                         if ($default === TRUE AND count($this->_field_data) === 0)
849                         {
850                                 return ' checked="checked"';
851                         }
852                         return '';
853                 }
854
855                 $field = $this->_field_data[$field]['postdata'];
856
857                 if (is_array($field))
858                 {
859                         if ( ! in_array($value, $field))
860                         {
861                                 return '';
862                         }
863                 }
864                 else
865                 {
866                         if (($field == '' OR $value == '') OR ($field != $value))
867                         {
868                                 return '';
869                         }
870                 }
871
872                 return ' checked="checked"';
873         }
874
875         // --------------------------------------------------------------------
876
877         /**
878          * Required
879          *
880          * @access      public
881          * @param       string
882          * @return      bool
883          */
884         function required($str)
885         {
886                 if ( ! is_array($str))
887                 {
888                         return (trim($str) == '') ? FALSE : TRUE;
889                 }
890                 else
891                 {
892                         return ( ! empty($str));
893                 }
894         }
895
896         // --------------------------------------------------------------------
897
898         /**
899          * Performs a Regular Expression match test.
900          *
901          * @access      public
902          * @param       string
903          * @param       regex
904          * @return      bool
905          */
906         function regex_match($str, $regex)
907         {
908                 if ( ! preg_match($regex, $str))
909                 {
910                         return FALSE;
911                 }
912
913                 return  TRUE;
914         }
915
916         // --------------------------------------------------------------------
917
918         /**
919          * Match one field to another
920          *
921          * @access      public
922          * @param       string
923          * @param       field
924          * @return      bool
925          */
926         function matches($str, $field)
927         {
928                 if ( ! isset($_POST[$field]))
929                 {
930                         return FALSE;
931                 }
932
933                 $field = $_POST[$field];
934
935                 return ($str !== $field) ? FALSE : TRUE;
936         }
937
938         // --------------------------------------------------------------------
939
940         /**
941          * Minimum Length
942          *
943          * @access      public
944          * @param       string
945          * @param       value
946          * @return      bool
947          */
948         function min_length($str, $val)
949         {
950                 if (preg_match("/[^0-9]/", $val))
951                 {
952                         return FALSE;
953                 }
954
955                 if (function_exists('mb_strlen'))
956                 {
957                         return (mb_strlen($str) < $val) ? FALSE : TRUE;
958                 }
959
960                 return (strlen($str) < $val) ? FALSE : TRUE;
961         }
962
963         // --------------------------------------------------------------------
964
965         /**
966          * Max Length
967          *
968          * @access      public
969          * @param       string
970          * @param       value
971          * @return      bool
972          */
973         function max_length($str, $val)
974         {
975                 if (preg_match("/[^0-9]/", $val))
976                 {
977                         return FALSE;
978                 }
979
980                 if (function_exists('mb_strlen'))
981                 {
982                         return (mb_strlen($str) > $val) ? FALSE : TRUE;
983                 }
984
985                 return (strlen($str) > $val) ? FALSE : TRUE;
986         }
987
988         // --------------------------------------------------------------------
989
990         /**
991          * Exact Length
992          *
993          * @access      public
994          * @param       string
995          * @param       value
996          * @return      bool
997          */
998         function exact_length($str, $val)
999         {
1000                 if (preg_match("/[^0-9]/", $val))
1001                 {
1002                         return FALSE;
1003                 }
1004
1005                 if (function_exists('mb_strlen'))
1006                 {
1007                         return (mb_strlen($str) != $val) ? FALSE : TRUE;
1008                 }
1009
1010                 return (strlen($str) != $val) ? FALSE : TRUE;
1011         }
1012
1013         // --------------------------------------------------------------------
1014
1015         /**
1016          * Valid Email
1017          *
1018          * @access      public
1019          * @param       string
1020          * @return      bool
1021          */
1022         function valid_email($str)
1023         {
1024                 return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
1025         }
1026
1027         // --------------------------------------------------------------------
1028
1029         /**
1030          * Valid Emails
1031          *
1032          * @access      public
1033          * @param       string
1034          * @return      bool
1035          */
1036         function valid_emails($str)
1037         {
1038                 if (strpos($str, ',') === FALSE)
1039                 {
1040                         return $this->valid_email(trim($str));
1041                 }
1042
1043                 foreach (explode(',', $str) as $email)
1044                 {
1045                         if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)
1046                         {
1047                                 return FALSE;
1048                         }
1049                 }
1050
1051                 return TRUE;
1052         }
1053
1054         // --------------------------------------------------------------------
1055
1056         /**
1057          * Validate IP Address
1058          *
1059          * @access      public
1060          * @param       string
1061          * @return      string
1062          */
1063         function valid_ip($ip)
1064         {
1065                 return $this->CI->input->valid_ip($ip);
1066         }
1067
1068         // --------------------------------------------------------------------
1069
1070         /**
1071          * Alpha
1072          *
1073          * @access      public
1074          * @param       string
1075          * @return      bool
1076          */
1077         function alpha($str)
1078         {
1079                 return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE;
1080         }
1081
1082         // --------------------------------------------------------------------
1083
1084         /**
1085          * Alpha-numeric
1086          *
1087          * @access      public
1088          * @param       string
1089          * @return      bool
1090          */
1091         function alpha_numeric($str)
1092         {
1093                 return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE;
1094         }
1095
1096         // --------------------------------------------------------------------
1097
1098         /**
1099          * Alpha-numeric with underscores and dashes
1100          *
1101          * @access      public
1102          * @param       string
1103          * @return      bool
1104          */
1105         function alpha_dash($str)
1106         {
1107                 return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;
1108         }
1109
1110         // --------------------------------------------------------------------
1111
1112         /**
1113          * Numeric
1114          *
1115          * @access      public
1116          * @param       string
1117          * @return      bool
1118          */
1119         function numeric($str)
1120         {
1121                 return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);
1122
1123         }
1124
1125         // --------------------------------------------------------------------
1126
1127         /**
1128          * Is Numeric
1129          *
1130          * @access      public
1131          * @param       string
1132          * @return      bool
1133          */
1134         function is_numeric($str)
1135         {
1136                 return ( ! is_numeric($str)) ? FALSE : TRUE;
1137         }
1138
1139         // --------------------------------------------------------------------
1140
1141         /**
1142          * Integer
1143          *
1144          * @access      public
1145          * @param       string
1146          * @return      bool
1147          */
1148         function integer($str)
1149         {
1150                 return (bool) preg_match('/^[\-+]?[0-9]+$/', $str);
1151         }
1152
1153         // --------------------------------------------------------------------
1154
1155         /**
1156          * Decimal number
1157          *
1158          * @access      public
1159          * @param       string
1160          * @return      bool
1161          */
1162         function decimal($str)
1163         {
1164                 return (bool) preg_match('/^[\-+]?[0-9]+\.[0-9]+$/', $str);
1165         }
1166
1167         // --------------------------------------------------------------------
1168
1169         /**
1170          * Greather than
1171          *
1172          * @access      public
1173          * @param       string
1174          * @return      bool
1175          */
1176         function greater_than($str, $min)
1177         {
1178                 if ( ! is_numeric($str))
1179                 {
1180                         return FALSE;
1181                 }
1182                 return $str > $min;
1183         }
1184
1185         // --------------------------------------------------------------------
1186
1187         /**
1188          * Less than
1189          *
1190          * @access      public
1191          * @param       string
1192          * @return      bool
1193          */
1194         function less_than($str, $max)
1195         {
1196                 if ( ! is_numeric($str))
1197                 {
1198                         return FALSE;
1199                 }
1200                 return $str < $max;
1201         }
1202
1203         // --------------------------------------------------------------------
1204
1205         /**
1206          * Is a Natural number  (0,1,2,3, etc.)
1207          *
1208          * @access      public
1209          * @param       string
1210          * @return      bool
1211          */
1212         function is_natural($str)
1213         {
1214                 return (bool) preg_match( '/^[0-9]+$/', $str);
1215         }
1216
1217         // --------------------------------------------------------------------
1218
1219         /**
1220          * Is a Natural number, but not a zero  (1,2,3, etc.)
1221          *
1222          * @access      public
1223          * @param       string
1224          * @return      bool
1225          */
1226         function is_natural_no_zero($str)
1227         {
1228                 if ( ! preg_match( '/^[0-9]+$/', $str))
1229                 {
1230                         return FALSE;
1231                 }
1232
1233                 if ($str == 0)
1234                 {
1235                         return FALSE;
1236                 }
1237
1238                 return TRUE;
1239         }
1240
1241         // --------------------------------------------------------------------
1242
1243         /**
1244          * Valid Base64
1245          *
1246          * Tests a string for characters outside of the Base64 alphabet
1247          * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045
1248          *
1249          * @access      public
1250          * @param       string
1251          * @return      bool
1252          */
1253         function valid_base64($str)
1254         {
1255                 return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str);
1256         }
1257
1258         // --------------------------------------------------------------------
1259
1260         /**
1261          * Prep data for form
1262          *
1263          * This function allows HTML to be safely shown in a form.
1264          * Special characters are converted.
1265          *
1266          * @access      public
1267          * @param       string
1268          * @return      string
1269          */
1270         function prep_for_form($data = '')
1271         {
1272                 if (is_array($data))
1273                 {
1274                         foreach ($data as $key => $val)
1275                         {
1276                                 $data[$key] = $this->prep_for_form($val);
1277                         }
1278
1279                         return $data;
1280                 }
1281
1282                 if ($this->_safe_form_data == FALSE OR $data === '')
1283                 {
1284                         return $data;
1285                 }
1286
1287                 return str_replace(array("'", '"', '<', '>'), array("&#39;", "&quot;", '&lt;', '&gt;'), stripslashes($data));
1288         }
1289
1290         // --------------------------------------------------------------------
1291
1292         /**
1293          * Prep URL
1294          *
1295          * @access      public
1296          * @param       string
1297          * @return      string
1298          */
1299         function prep_url($str = '')
1300         {
1301                 if ($str == 'http://' OR $str == '')
1302                 {
1303                         return '';
1304                 }
1305
1306                 if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')
1307                 {
1308                         $str = 'http://'.$str;
1309                 }
1310
1311                 return $str;
1312         }
1313
1314         // --------------------------------------------------------------------
1315
1316         /**
1317          * Strip Image Tags
1318          *
1319          * @access      public
1320          * @param       string
1321          * @return      string
1322          */
1323         function strip_image_tags($str)
1324         {
1325                 return $this->CI->input->strip_image_tags($str);
1326         }
1327
1328         // --------------------------------------------------------------------
1329
1330         /**
1331          * XSS Clean
1332          *
1333          * @access      public
1334          * @param       string
1335          * @return      string
1336          */
1337         function xss_clean($str)
1338         {
1339                 return $this->CI->security->xss_clean($str);
1340         }
1341
1342         // --------------------------------------------------------------------
1343
1344         /**
1345          * Convert PHP tags to entities
1346          *
1347          * @access      public
1348          * @param       string
1349          * @return      string
1350          */
1351         function encode_php_tags($str)
1352         {
1353                 return str_replace(array('<?php', '<?PHP', '<?', '?>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
1354         }
1355
1356 }
1357 // END Form Validation Class
1358
1359 /* End of file Form_validation.php */
1360 /* Location: ./system/libraries/Form_validation.php */