blob: 5322be0e9b9c2e3f16ba8d2284fdeb0261cd109a [file] [log] [blame]
adminb0dd10f2006-08-25 17:25:49 +00001<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * Code Igniter
4 *
5 * An open source application development framework for PHP 4.3.2 or newer
6 *
7 * @package CodeIgniter
8 * @author Rick Ellis
9 * @copyright Copyright (c) 2006, pMachine, Inc.
10 * @license http://www.codeignitor.com/user_guide/license.html
11 * @link http://www.codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
admine79dc712006-09-26 03:52:45 +000015
adminb0dd10f2006-08-25 17:25:49 +000016// ------------------------------------------------------------------------
17
18/**
19 * Validation Class
20 *
21 * @package CodeIgniter
22 * @subpackage Libraries
23 * @category Validation
24 * @author Rick Ellis
25 * @link http://www.codeigniter.com/user_guide/libraries/validation.html
26 */
27class CI_Validation {
28
adminb3ab70b2006-10-07 03:07:29 +000029 var $CI;
adminb0dd10f2006-08-25 17:25:49 +000030 var $error_string = '';
31 var $_error_array = array();
32 var $_rules = array();
33 var $_fields = array();
34 var $_error_messages = array();
35 var $_current_field = '';
36 var $_safe_form_data = FALSE;
37 var $_error_prefix = '<p>';
38 var $_error_suffix = '</p>';
adminb3ab70b2006-10-07 03:07:29 +000039
adminb0dd10f2006-08-25 17:25:49 +000040
41
42 /**
43 * Constructor
44 *
45 */
46 function CI_Validation()
47 {
adminb3ab70b2006-10-07 03:07:29 +000048 $this->CI =& get_instance();
adminb0dd10f2006-08-25 17:25:49 +000049 log_message('debug', "Validation Class Initialized");
50 }
51
52 // --------------------------------------------------------------------
53
54 /**
55 * Set Fields
56 *
57 * This function takes an array of field names as input
58 * and generates class variables with the same name, which will
59 * either be blank or contain the $_POST value corresponding to it
60 *
61 * @access public
62 * @param string
63 * @param string
64 * @return void
65 */
66 function set_fields($data = '', $field = '')
67 {
68 if ($data == '')
adminb0dd10f2006-08-25 17:25:49 +000069 {
adminc5f7fa32006-10-06 02:10:23 +000070 if (count($this->_fields) == 0)
71 {
72 return FALSE;
73 }
adminb0dd10f2006-08-25 17:25:49 +000074 }
adminc5f7fa32006-10-06 02:10:23 +000075 else
76 {
77 if ( ! is_array($data))
78 {
79 $data = array($data => $field);
80 }
81
82 if (count($data) > 0)
83 {
84 $this->_fields = $data;
85 }
86 }
87
adminb0dd10f2006-08-25 17:25:49 +000088 foreach($this->_fields as $key => $val)
89 {
90 $this->$key = ( ! isset($_POST[$key]) OR is_array($_POST[$key])) ? '' : $this->prep_for_form($_POST[$key]);
91
92 $error = $key.'_error';
93 if ( ! isset($this->$error))
94 {
95 $this->$error = '';
96 }
97 }
98 }
99
100 // --------------------------------------------------------------------
101
102 /**
103 * Set Rules
104 *
105 * This function takes an array of field names and validation
106 * rules as input ad simply stores is for use later.
107 *
108 * @access public
109 * @param mixed
110 * @param string
111 * @return void
112 */
113 function set_rules($data, $rules = '')
114 {
115 if ( ! is_array($data))
116 {
117 if ($rules == '')
118 return;
119
120 $data[$data] = $rules;
121 }
122
123 foreach ($data as $key => $val)
124 {
125 $this->_rules[$key] = $val;
126 }
127 }
128
129 // --------------------------------------------------------------------
130
131 /**
132 * Set Error Message
133 *
134 * Lets users set their own error messages on the fly. Note: The key
135 * name has to match the function name that it corresponds to.
136 *
137 * @access public
138 * @param string
139 * @param string
140 * @return string
141 */
142 function set_message($lang, $val = '')
143 {
144 if ( ! is_array($lang))
145 {
146 $lang = array($lang => $val);
147 }
148
149 $this->_error_messages = array_merge($this->_error_messages, $lang);
150 }
151
152 // --------------------------------------------------------------------
153
154 /**
155 * Set The Error Delimiter
156 *
157 * Permits a prefix/suffix to be added to each error message
158 *
159 * @access public
160 * @param string
161 * @param string
162 * @return void
163 */
164 function set_error_delimiters($prefix = '<p>', $suffix = '</p>')
165 {
166 $this->_error_prefix = $prefix;
167 $this->_error_suffix = $suffix;
168 }
169
170 // --------------------------------------------------------------------
171
172 /**
173 * Run the Validator
174 *
175 * This function does all the work.
176 *
177 * @access public
178 * @return bool
179 */
180 function run()
181 {
182 // Do we even have any data to process? Mm?
183 if (count($_POST) == 0 OR count($this->_rules) == 0)
184 {
185 return FALSE;
186 }
187
188 // Load the language file containing error messages
adminb3ab70b2006-10-07 03:07:29 +0000189 $this->CI->lang->load('validation');
adminb0dd10f2006-08-25 17:25:49 +0000190
191 // Cycle through the rules and test for errors
192 foreach ($this->_rules as $field => $rules)
193 {
194 //Explode out the rules!
195 $ex = explode('|', $rules);
196
197 // Is the field required? If not, if the field is blank we'll move on to the next text
adminee54c112006-09-28 17:13:38 +0000198 if ( ! in_array('required', $ex, TRUE) AND strpos($rules, 'callback_') === FALSE)
adminb0dd10f2006-08-25 17:25:49 +0000199 {
200 if ( ! isset($_POST[$field]) OR $_POST[$field] == '')
201 {
202 continue;
203 }
204 }
205
206 /*
207 * Are we dealing with an "isset" rule?
208 *
209 * Before going further, we'll see if one of the rules
210 * is to check whether the item is set (typically this
211 * applies only to checkboxes). If so, we'll
212 * test for it here since there's not reason to go
213 * further
214 */
215 if ( ! isset($_POST[$field]))
216 {
adminee54c112006-09-28 17:13:38 +0000217 if (in_array('isset', $ex, TRUE) OR in_array('required', $ex))
adminb0dd10f2006-08-25 17:25:49 +0000218 {
admineb6db842006-09-02 02:39:45 +0000219 if ( ! isset($this->_error_messages['isset']))
adminb0dd10f2006-08-25 17:25:49 +0000220 {
adminb3ab70b2006-10-07 03:07:29 +0000221 if (FALSE === ($line = $this->CI->lang->line('isset')))
adminb0dd10f2006-08-25 17:25:49 +0000222 {
223 $line = 'The field was not set';
224 }
225 }
226 else
227 {
228 $line = $this->_error_messages['isset'];
229 }
230
231 $field = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
232 $this->_error_array[] = sprintf($line, $field);
233 }
234
235 continue;
236 }
237
238 /*
239 * Set the current field
240 *
241 * The various prepping functions need to know the
242 * current field name so they can do this:
243 *
244 * $_POST[$this->_current_field] == 'bla bla';
245 */
246 $this->_current_field = $field;
247
248 // Cycle through the rules!
249 foreach ($ex As $rule)
250 {
adminb0dd10f2006-08-25 17:25:49 +0000251 // Is the rule a callback?
252 $callback = FALSE;
253 if (substr($rule, 0, 9) == 'callback_')
254 {
255 $rule = substr($rule, 9);
256 $callback = TRUE;
admine348efb2006-09-20 21:13:26 +0000257 }
258
adminb0dd10f2006-08-25 17:25:49 +0000259 // Strip the parameter (if exists) from the rule
260 // Rules can contain a parameter: max_length[5]
261 $param = FALSE;
admin141808a2006-08-27 01:52:51 +0000262 if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))
adminb0dd10f2006-08-25 17:25:49 +0000263 {
admin141808a2006-08-27 01:52:51 +0000264 $rule = $match[1];
265 $param = $match[2];
adminb0dd10f2006-08-25 17:25:49 +0000266 }
admin141808a2006-08-27 01:52:51 +0000267
adminb0dd10f2006-08-25 17:25:49 +0000268 // Call the function that corresponds to the rule
269 if ($callback === TRUE)
270 {
adminb3ab70b2006-10-07 03:07:29 +0000271 if ( ! method_exists($this->CI, $rule))
adminb0dd10f2006-08-25 17:25:49 +0000272 {
273 continue;
274 }
275
adminb3ab70b2006-10-07 03:07:29 +0000276 $result = $this->CI->$rule($_POST[$field], $param);
admin89a8b972006-09-18 15:46:28 +0000277
admine348efb2006-09-20 21:13:26 +0000278 // If the field isn't required and we just processed a callback we'll move on...
adminee54c112006-09-28 17:13:38 +0000279 if ( ! in_array('required', $ex, TRUE) AND $result !== FALSE)
admin89a8b972006-09-18 15:46:28 +0000280 {
admine348efb2006-09-20 21:13:26 +0000281 continue 2;
admin89a8b972006-09-18 15:46:28 +0000282 }
admine348efb2006-09-20 21:13:26 +0000283
adminb0dd10f2006-08-25 17:25:49 +0000284 }
285 else
286 {
287 if ( ! method_exists($this, $rule))
288 {
289 /*
290 * Run the native PHP function if called for
291 *
292 * If our own wrapper function doesn't exist we see
293 * if a native PHP function does. Users can use
294 * any native PHP function call that has one param.
295 */
296 if (function_exists($rule))
297 {
298 $_POST[$field] = $rule($_POST[$field]);
299 $this->$field = $_POST[$field];
300 }
301
302 continue;
303 }
304
305 $result = $this->$rule($_POST[$field], $param);
306 }
admine348efb2006-09-20 21:13:26 +0000307
adminb0dd10f2006-08-25 17:25:49 +0000308 // Did the rule test negatively? If so, grab the error.
309 if ($result === FALSE)
310 {
311 if ( ! isset($this->_error_messages[$rule]))
312 {
adminb3ab70b2006-10-07 03:07:29 +0000313 if (FALSE === ($line = $this->CI->lang->line($rule)))
adminb0dd10f2006-08-25 17:25:49 +0000314 {
315 $line = 'Unable to access an error message corresponding to your field name.';
316 }
317 }
318 else
319 {
320 $line = $this->_error_messages[$rule];;
321 }
322
323 // Build the error message
324 $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
325 $mparam = ( ! isset($this->_fields[$param])) ? $param : $this->_fields[$param];
326 $message = sprintf($line, $mfield, $mparam);
327
328 // Set the error variable. Example: $this->username_error
329 $error = $field.'_error';
330 $this->$error = $this->_error_prefix.$message.$this->_error_suffix;
331
332 // Add the error to the error array
333 $this->_error_array[] = $message;
334 continue 2;
admine348efb2006-09-20 21:13:26 +0000335 }
adminb0dd10f2006-08-25 17:25:49 +0000336 }
admine348efb2006-09-20 21:13:26 +0000337
adminb0dd10f2006-08-25 17:25:49 +0000338 }
339
340 $total_errors = count($this->_error_array);
341
342 /*
343 * Recompile the class variables
344 *
345 * If any prepping functions were called the $_POST data
346 * might now be different then the corresponding class
347 * variables so we'll set them anew.
348 */
349 if ($total_errors > 0)
350 {
351 $this->_safe_form_data = TRUE;
352 }
353
354 $this->set_fields();
355
356 // Did we end up with any errors?
357 if ($total_errors == 0)
358 {
359 return TRUE;
360 }
361
362 // Generate the error string
363 foreach ($this->_error_array as $val)
364 {
365 $this->error_string .= $this->_error_prefix.$val.$this->_error_suffix."\n";
366 }
367
368 return FALSE;
369 }
370
371 // --------------------------------------------------------------------
372
373 /**
374 * Required
375 *
376 * @access public
377 * @param string
378 * @return bool
379 */
380 function required($str)
381 {
382 if ( ! is_array($str))
383 {
384 return (trim($str) == '') ? FALSE : TRUE;
385 }
386 else
387 {
388 return ( ! empty($str));
389 }
390 }
391
392 // --------------------------------------------------------------------
393
394 /**
395 * Match one field to another
396 *
397 * @access public
398 * @param string
399 * @return bool
400 */
401 function matches($str, $field)
402 {
403 if ( ! isset($_POST[$field]))
404 {
405 return FALSE;
406 }
407
408 return ($str !== $_POST[$field]) ? FALSE : TRUE;
409 }
410
411 // --------------------------------------------------------------------
412
413 /**
414 * Minimum Length
415 *
416 * @access public
417 * @param string
418 * @return bool
419 */
420 function min_length($str, $val)
421 {
admin1cf89aa2006-09-03 18:24:39 +0000422 if ( ! is_numeric($val))
adminb0dd10f2006-08-25 17:25:49 +0000423 {
424 return FALSE;
425 }
426
427 return (strlen($str) < $val) ? FALSE : TRUE;
428 }
429
430 // --------------------------------------------------------------------
431
432 /**
433 * Max Length
434 *
435 * @access public
436 * @param string
437 * @return bool
438 */
439 function max_length($str, $val)
440 {
admin1cf89aa2006-09-03 18:24:39 +0000441 if ( ! is_numeric($val))
adminb0dd10f2006-08-25 17:25:49 +0000442 {
443 return FALSE;
444 }
445
446 return (strlen($str) > $val) ? FALSE : TRUE;
447 }
448
449 // --------------------------------------------------------------------
450
451 /**
452 * Exact Length
453 *
454 * @access public
455 * @param string
456 * @return bool
457 */
458 function exact_length($str, $val)
459 {
admin1cf89aa2006-09-03 18:24:39 +0000460 if ( ! is_numeric($val))
adminb0dd10f2006-08-25 17:25:49 +0000461 {
462 return FALSE;
463 }
464
465 return (strlen($str) != $val) ? FALSE : TRUE;
466 }
467
468 // --------------------------------------------------------------------
469
470 /**
471 * Valid Email
472 *
473 * @access public
474 * @param string
475 * @return bool
476 */
477 function valid_email($str)
478 {
479 return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
480 }
481
482 // --------------------------------------------------------------------
483
484 /**
485 * Alpha
486 *
487 * @access public
488 * @param string
489 * @return bool
490 */
491 function alpha($str)
492 {
493 return ( ! preg_match("/^([-a-z])+$/i", $str)) ? FALSE : TRUE;
494 }
495
496 // --------------------------------------------------------------------
497
498 /**
499 * Alpha-numeric
500 *
501 * @access public
502 * @param string
503 * @return bool
504 */
505 function alpha_numeric($str)
506 {
507 return ( ! preg_match("/^([-a-z0-9])+$/i", $str)) ? FALSE : TRUE;
508 }
509
510 // --------------------------------------------------------------------
511
512 /**
513 * Alpha-numeric with underscores and dashes
514 *
515 * @access public
516 * @param string
517 * @return bool
518 */
519 function alpha_dash($str)
520 {
521 return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;
522 }
523
524 // --------------------------------------------------------------------
525
526 /**
527 * Numeric
528 *
529 * @access public
admin83b05a82006-09-25 21:06:46 +0000530 * @param int
adminb0dd10f2006-08-25 17:25:49 +0000531 * @return bool
532 */
533 function numeric($str)
534 {
admin3c023b12006-09-24 03:04:10 +0000535 return ( ! ereg("^[0-9\.]+$", $str)) ? FALSE : TRUE;
adminb0dd10f2006-08-25 17:25:49 +0000536 }
admin83b05a82006-09-25 21:06:46 +0000537
538 // --------------------------------------------------------------------
539
540 /**
541 * Is Numeric
542 *
543 * @access public
544 * @param string
545 * @return bool
546 */
547 function is_numeric($str)
548 {
549 return ( ! is_numeric($str)) ? FALSE : TRUE;
550 }
adminb0dd10f2006-08-25 17:25:49 +0000551
552 // --------------------------------------------------------------------
553
554 /**
555 * Set Select
556 *
557 * Enables pull-down lists to be set to the value the user
558 * selected in the event of an error
559 *
560 * @access public
561 * @param string
562 * @param string
563 * @return string
564 */
565 function set_select($field = '', $value = '')
566 {
567 if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
568 {
569 return '';
570 }
571
572 if ($_POST[$field] == $value)
573 {
574 return ' selected="selected"';
575 }
576 }
577
578 // --------------------------------------------------------------------
579
580 /**
581 * Set Radio
582 *
583 * Enables radio buttons to be set to the value the user
584 * selected in the event of an error
585 *
586 * @access public
587 * @param string
588 * @param string
589 * @return string
590 */
591 function set_radio($field = '', $value = '')
592 {
593 if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
594 {
595 return '';
596 }
597
598 if ($_POST[$field] == $value)
599 {
600 return ' checked="checked"';
601 }
602 }
603
604 // --------------------------------------------------------------------
605
606 /**
607 * Set Checkbox
608 *
609 * Enables checkboxes to be set to the value the user
610 * selected in the event of an error
611 *
612 * @access public
613 * @param string
614 * @param string
615 * @return string
616 */
617 function set_checkbox($field = '', $value = '')
618 {
619 if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
620 {
621 return '';
622 }
623
624 if ($_POST[$field] == $value)
625 {
626 return ' checked="checked"';
627 }
628 }
629
630 // --------------------------------------------------------------------
631
632 /**
633 * Prep data for form
634 *
635 * This function allows HTML to be safely shown in a form.
636 * Special characters are converted.
637 *
638 * @access public
639 * @param string
640 * @return string
641 */
642 function prep_for_form($str = '')
643 {
644 if ($this->_safe_form_data == FALSE OR $str == '')
645 {
646 return $str;
647 }
648
649 return str_replace(array("'", '"', '<', '>'), array("&#39;", "&quot;", '&lt;', '&gt;'), stripslashes($str));
650 }
651
652 // --------------------------------------------------------------------
653
654 /**
655 * Prep URL
656 *
657 * @access public
658 * @param string
659 * @return string
660 */
661 function prep_url($str = '')
662 {
663 if ($str == 'http://' OR $str == '')
664 {
665 $_POST[$this->_current_field] = '';
666 return;
667 }
668
669 if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')
670 {
671 $str = 'http://'.$str;
672 }
673
674 $_POST[$this->_current_field] = $str;
675 }
676
677 // --------------------------------------------------------------------
678
679 /**
680 * Strip Image Tags
681 *
682 * @access public
683 * @param string
684 * @return string
685 */
686 function strip_image_tags($str)
687 {
688 $_POST[$this->_current_field] = $this->input->strip_image_tags($str);
689 }
690
691 // --------------------------------------------------------------------
692
693 /**
694 * XSS Clean
695 *
696 * @access public
697 * @param string
698 * @return string
699 */
700 function xss_clean($str)
701 {
adminb3ab70b2006-10-07 03:07:29 +0000702 $_POST[$this->_current_field] = $this->CI->input->xss_clean($str);
adminb0dd10f2006-08-25 17:25:49 +0000703 }
704
705 // --------------------------------------------------------------------
706
707 /**
708 * Convert PHP tags to entities
709 *
710 * @access public
711 * @param string
712 * @return string
713 */
714 function encode_php_tags($str)
715 {
716 $_POST[$this->_current_field] = str_replace(array('<?php', '<?PHP', '<?', '?>'), array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
717 }
718
719}
720// END Validation Class
721?>