blob: 7db67a3e150d4c303dae8e5d6da9ddeb8858d69e [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
29 var $error_string = '';
30 var $_error_array = array();
31 var $_rules = array();
32 var $_fields = array();
33 var $_error_messages = array();
34 var $_current_field = '';
35 var $_safe_form_data = FALSE;
36 var $_error_prefix = '<p>';
37 var $_error_suffix = '</p>';
38 var $obj;
39
40
41 /**
42 * Constructor
43 *
44 */
45 function CI_Validation()
46 {
47 $this->obj =& get_instance();
48 log_message('debug', "Validation Class Initialized");
49 }
50
51 // --------------------------------------------------------------------
52
53 /**
54 * Set Fields
55 *
56 * This function takes an array of field names as input
57 * and generates class variables with the same name, which will
58 * either be blank or contain the $_POST value corresponding to it
59 *
60 * @access public
61 * @param string
62 * @param string
63 * @return void
64 */
65 function set_fields($data = '', $field = '')
66 {
67 if ($data == '')
68 return;
69
70 if ( ! is_array($data))
71 {
72 if ($field == '')
73 return;
74
75 $data = array($data => $field);
76 }
77
78 $this->_fields = $data;
79
80 foreach($this->_fields as $key => $val)
81 {
82 $this->$key = ( ! isset($_POST[$key]) OR is_array($_POST[$key])) ? '' : $this->prep_for_form($_POST[$key]);
83
84 $error = $key.'_error';
85 if ( ! isset($this->$error))
86 {
87 $this->$error = '';
88 }
89 }
90 }
91
92 // --------------------------------------------------------------------
93
94 /**
95 * Set Rules
96 *
97 * This function takes an array of field names and validation
98 * rules as input ad simply stores is for use later.
99 *
100 * @access public
101 * @param mixed
102 * @param string
103 * @return void
104 */
105 function set_rules($data, $rules = '')
106 {
107 if ( ! is_array($data))
108 {
109 if ($rules == '')
110 return;
111
112 $data[$data] = $rules;
113 }
114
115 foreach ($data as $key => $val)
116 {
117 $this->_rules[$key] = $val;
118 }
119 }
120
121 // --------------------------------------------------------------------
122
123 /**
124 * Set Error Message
125 *
126 * Lets users set their own error messages on the fly. Note: The key
127 * name has to match the function name that it corresponds to.
128 *
129 * @access public
130 * @param string
131 * @param string
132 * @return string
133 */
134 function set_message($lang, $val = '')
135 {
136 if ( ! is_array($lang))
137 {
138 $lang = array($lang => $val);
139 }
140
141 $this->_error_messages = array_merge($this->_error_messages, $lang);
142 }
143
144 // --------------------------------------------------------------------
145
146 /**
147 * Set The Error Delimiter
148 *
149 * Permits a prefix/suffix to be added to each error message
150 *
151 * @access public
152 * @param string
153 * @param string
154 * @return void
155 */
156 function set_error_delimiters($prefix = '<p>', $suffix = '</p>')
157 {
158 $this->_error_prefix = $prefix;
159 $this->_error_suffix = $suffix;
160 }
161
162 // --------------------------------------------------------------------
163
164 /**
165 * Run the Validator
166 *
167 * This function does all the work.
168 *
169 * @access public
170 * @return bool
171 */
172 function run()
173 {
174 // Do we even have any data to process? Mm?
175 if (count($_POST) == 0 OR count($this->_rules) == 0)
176 {
177 return FALSE;
178 }
179
180 // Load the language file containing error messages
181 $this->obj->lang->load('validation');
182
183 // Cycle through the rules and test for errors
184 foreach ($this->_rules as $field => $rules)
185 {
186 //Explode out the rules!
187 $ex = explode('|', $rules);
188
189 // 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 +0000190 if ( ! in_array('required', $ex, TRUE) AND strpos($rules, 'callback_') === FALSE)
adminb0dd10f2006-08-25 17:25:49 +0000191 {
192 if ( ! isset($_POST[$field]) OR $_POST[$field] == '')
193 {
194 continue;
195 }
196 }
197
198 /*
199 * Are we dealing with an "isset" rule?
200 *
201 * Before going further, we'll see if one of the rules
202 * is to check whether the item is set (typically this
203 * applies only to checkboxes). If so, we'll
204 * test for it here since there's not reason to go
205 * further
206 */
207 if ( ! isset($_POST[$field]))
208 {
adminee54c112006-09-28 17:13:38 +0000209 if (in_array('isset', $ex, TRUE) OR in_array('required', $ex))
adminb0dd10f2006-08-25 17:25:49 +0000210 {
admineb6db842006-09-02 02:39:45 +0000211 if ( ! isset($this->_error_messages['isset']))
adminb0dd10f2006-08-25 17:25:49 +0000212 {
213 if (FALSE === ($line = $this->obj->lang->line('isset')))
214 {
215 $line = 'The field was not set';
216 }
217 }
218 else
219 {
220 $line = $this->_error_messages['isset'];
221 }
222
223 $field = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
224 $this->_error_array[] = sprintf($line, $field);
225 }
226
227 continue;
228 }
229
230 /*
231 * Set the current field
232 *
233 * The various prepping functions need to know the
234 * current field name so they can do this:
235 *
236 * $_POST[$this->_current_field] == 'bla bla';
237 */
238 $this->_current_field = $field;
239
240 // Cycle through the rules!
241 foreach ($ex As $rule)
242 {
adminb0dd10f2006-08-25 17:25:49 +0000243 // Is the rule a callback?
244 $callback = FALSE;
245 if (substr($rule, 0, 9) == 'callback_')
246 {
247 $rule = substr($rule, 9);
248 $callback = TRUE;
admine348efb2006-09-20 21:13:26 +0000249 }
250
adminb0dd10f2006-08-25 17:25:49 +0000251 // Strip the parameter (if exists) from the rule
252 // Rules can contain a parameter: max_length[5]
253 $param = FALSE;
admin141808a2006-08-27 01:52:51 +0000254 if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))
adminb0dd10f2006-08-25 17:25:49 +0000255 {
admin141808a2006-08-27 01:52:51 +0000256 $rule = $match[1];
257 $param = $match[2];
adminb0dd10f2006-08-25 17:25:49 +0000258 }
admin141808a2006-08-27 01:52:51 +0000259
adminb0dd10f2006-08-25 17:25:49 +0000260 // Call the function that corresponds to the rule
261 if ($callback === TRUE)
262 {
263 if ( ! method_exists($this->obj, $rule))
264 {
265 continue;
266 }
267
admine348efb2006-09-20 21:13:26 +0000268 $result = $this->obj->$rule($_POST[$field], $param);
admin89a8b972006-09-18 15:46:28 +0000269
admine348efb2006-09-20 21:13:26 +0000270 // If the field isn't required and we just processed a callback we'll move on...
adminee54c112006-09-28 17:13:38 +0000271 if ( ! in_array('required', $ex, TRUE) AND $result !== FALSE)
admin89a8b972006-09-18 15:46:28 +0000272 {
admine348efb2006-09-20 21:13:26 +0000273 continue 2;
admin89a8b972006-09-18 15:46:28 +0000274 }
admine348efb2006-09-20 21:13:26 +0000275
adminb0dd10f2006-08-25 17:25:49 +0000276 }
277 else
278 {
279 if ( ! method_exists($this, $rule))
280 {
281 /*
282 * Run the native PHP function if called for
283 *
284 * If our own wrapper function doesn't exist we see
285 * if a native PHP function does. Users can use
286 * any native PHP function call that has one param.
287 */
288 if (function_exists($rule))
289 {
290 $_POST[$field] = $rule($_POST[$field]);
291 $this->$field = $_POST[$field];
292 }
293
294 continue;
295 }
296
297 $result = $this->$rule($_POST[$field], $param);
298 }
admine348efb2006-09-20 21:13:26 +0000299
adminb0dd10f2006-08-25 17:25:49 +0000300 // Did the rule test negatively? If so, grab the error.
301 if ($result === FALSE)
302 {
303 if ( ! isset($this->_error_messages[$rule]))
304 {
305 if (FALSE === ($line = $this->obj->lang->line($rule)))
306 {
307 $line = 'Unable to access an error message corresponding to your field name.';
308 }
309 }
310 else
311 {
312 $line = $this->_error_messages[$rule];;
313 }
314
315 // Build the error message
316 $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
317 $mparam = ( ! isset($this->_fields[$param])) ? $param : $this->_fields[$param];
318 $message = sprintf($line, $mfield, $mparam);
319
320 // Set the error variable. Example: $this->username_error
321 $error = $field.'_error';
322 $this->$error = $this->_error_prefix.$message.$this->_error_suffix;
323
324 // Add the error to the error array
325 $this->_error_array[] = $message;
326 continue 2;
admine348efb2006-09-20 21:13:26 +0000327 }
adminb0dd10f2006-08-25 17:25:49 +0000328 }
admine348efb2006-09-20 21:13:26 +0000329
adminb0dd10f2006-08-25 17:25:49 +0000330 }
331
332 $total_errors = count($this->_error_array);
333
334 /*
335 * Recompile the class variables
336 *
337 * If any prepping functions were called the $_POST data
338 * might now be different then the corresponding class
339 * variables so we'll set them anew.
340 */
341 if ($total_errors > 0)
342 {
343 $this->_safe_form_data = TRUE;
344 }
345
346 $this->set_fields();
347
348 // Did we end up with any errors?
349 if ($total_errors == 0)
350 {
351 return TRUE;
352 }
353
354 // Generate the error string
355 foreach ($this->_error_array as $val)
356 {
357 $this->error_string .= $this->_error_prefix.$val.$this->_error_suffix."\n";
358 }
359
360 return FALSE;
361 }
362
363 // --------------------------------------------------------------------
364
365 /**
366 * Required
367 *
368 * @access public
369 * @param string
370 * @return bool
371 */
372 function required($str)
373 {
374 if ( ! is_array($str))
375 {
376 return (trim($str) == '') ? FALSE : TRUE;
377 }
378 else
379 {
380 return ( ! empty($str));
381 }
382 }
383
384 // --------------------------------------------------------------------
385
386 /**
387 * Match one field to another
388 *
389 * @access public
390 * @param string
391 * @return bool
392 */
393 function matches($str, $field)
394 {
395 if ( ! isset($_POST[$field]))
396 {
397 return FALSE;
398 }
399
400 return ($str !== $_POST[$field]) ? FALSE : TRUE;
401 }
402
403 // --------------------------------------------------------------------
404
405 /**
406 * Minimum Length
407 *
408 * @access public
409 * @param string
410 * @return bool
411 */
412 function min_length($str, $val)
413 {
admin1cf89aa2006-09-03 18:24:39 +0000414 if ( ! is_numeric($val))
adminb0dd10f2006-08-25 17:25:49 +0000415 {
416 return FALSE;
417 }
418
419 return (strlen($str) < $val) ? FALSE : TRUE;
420 }
421
422 // --------------------------------------------------------------------
423
424 /**
425 * Max Length
426 *
427 * @access public
428 * @param string
429 * @return bool
430 */
431 function max_length($str, $val)
432 {
admin1cf89aa2006-09-03 18:24:39 +0000433 if ( ! is_numeric($val))
adminb0dd10f2006-08-25 17:25:49 +0000434 {
435 return FALSE;
436 }
437
438 return (strlen($str) > $val) ? FALSE : TRUE;
439 }
440
441 // --------------------------------------------------------------------
442
443 /**
444 * Exact Length
445 *
446 * @access public
447 * @param string
448 * @return bool
449 */
450 function exact_length($str, $val)
451 {
admin1cf89aa2006-09-03 18:24:39 +0000452 if ( ! is_numeric($val))
adminb0dd10f2006-08-25 17:25:49 +0000453 {
454 return FALSE;
455 }
456
457 return (strlen($str) != $val) ? FALSE : TRUE;
458 }
459
460 // --------------------------------------------------------------------
461
462 /**
463 * Valid Email
464 *
465 * @access public
466 * @param string
467 * @return bool
468 */
469 function valid_email($str)
470 {
471 return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
472 }
473
474 // --------------------------------------------------------------------
475
476 /**
477 * Alpha
478 *
479 * @access public
480 * @param string
481 * @return bool
482 */
483 function alpha($str)
484 {
485 return ( ! preg_match("/^([-a-z])+$/i", $str)) ? FALSE : TRUE;
486 }
487
488 // --------------------------------------------------------------------
489
490 /**
491 * Alpha-numeric
492 *
493 * @access public
494 * @param string
495 * @return bool
496 */
497 function alpha_numeric($str)
498 {
499 return ( ! preg_match("/^([-a-z0-9])+$/i", $str)) ? FALSE : TRUE;
500 }
501
502 // --------------------------------------------------------------------
503
504 /**
505 * Alpha-numeric with underscores and dashes
506 *
507 * @access public
508 * @param string
509 * @return bool
510 */
511 function alpha_dash($str)
512 {
513 return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;
514 }
515
516 // --------------------------------------------------------------------
517
518 /**
519 * Numeric
520 *
521 * @access public
admin83b05a82006-09-25 21:06:46 +0000522 * @param int
adminb0dd10f2006-08-25 17:25:49 +0000523 * @return bool
524 */
525 function numeric($str)
526 {
admin3c023b12006-09-24 03:04:10 +0000527 return ( ! ereg("^[0-9\.]+$", $str)) ? FALSE : TRUE;
adminb0dd10f2006-08-25 17:25:49 +0000528 }
admin83b05a82006-09-25 21:06:46 +0000529
530 // --------------------------------------------------------------------
531
532 /**
533 * Is Numeric
534 *
535 * @access public
536 * @param string
537 * @return bool
538 */
539 function is_numeric($str)
540 {
541 return ( ! is_numeric($str)) ? FALSE : TRUE;
542 }
adminb0dd10f2006-08-25 17:25:49 +0000543
544 // --------------------------------------------------------------------
545
546 /**
547 * Set Select
548 *
549 * Enables pull-down lists to be set to the value the user
550 * selected in the event of an error
551 *
552 * @access public
553 * @param string
554 * @param string
555 * @return string
556 */
557 function set_select($field = '', $value = '')
558 {
559 if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
560 {
561 return '';
562 }
563
564 if ($_POST[$field] == $value)
565 {
566 return ' selected="selected"';
567 }
568 }
569
570 // --------------------------------------------------------------------
571
572 /**
573 * Set Radio
574 *
575 * Enables radio buttons to be set to the value the user
576 * selected in the event of an error
577 *
578 * @access public
579 * @param string
580 * @param string
581 * @return string
582 */
583 function set_radio($field = '', $value = '')
584 {
585 if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
586 {
587 return '';
588 }
589
590 if ($_POST[$field] == $value)
591 {
592 return ' checked="checked"';
593 }
594 }
595
596 // --------------------------------------------------------------------
597
598 /**
599 * Set Checkbox
600 *
601 * Enables checkboxes to be set to the value the user
602 * selected in the event of an error
603 *
604 * @access public
605 * @param string
606 * @param string
607 * @return string
608 */
609 function set_checkbox($field = '', $value = '')
610 {
611 if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
612 {
613 return '';
614 }
615
616 if ($_POST[$field] == $value)
617 {
618 return ' checked="checked"';
619 }
620 }
621
622 // --------------------------------------------------------------------
623
624 /**
625 * Prep data for form
626 *
627 * This function allows HTML to be safely shown in a form.
628 * Special characters are converted.
629 *
630 * @access public
631 * @param string
632 * @return string
633 */
634 function prep_for_form($str = '')
635 {
636 if ($this->_safe_form_data == FALSE OR $str == '')
637 {
638 return $str;
639 }
640
641 return str_replace(array("'", '"', '<', '>'), array("&#39;", "&quot;", '&lt;', '&gt;'), stripslashes($str));
642 }
643
644 // --------------------------------------------------------------------
645
646 /**
647 * Prep URL
648 *
649 * @access public
650 * @param string
651 * @return string
652 */
653 function prep_url($str = '')
654 {
655 if ($str == 'http://' OR $str == '')
656 {
657 $_POST[$this->_current_field] = '';
658 return;
659 }
660
661 if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')
662 {
663 $str = 'http://'.$str;
664 }
665
666 $_POST[$this->_current_field] = $str;
667 }
668
669 // --------------------------------------------------------------------
670
671 /**
672 * Strip Image Tags
673 *
674 * @access public
675 * @param string
676 * @return string
677 */
678 function strip_image_tags($str)
679 {
680 $_POST[$this->_current_field] = $this->input->strip_image_tags($str);
681 }
682
683 // --------------------------------------------------------------------
684
685 /**
686 * XSS Clean
687 *
688 * @access public
689 * @param string
690 * @return string
691 */
692 function xss_clean($str)
693 {
694 $_POST[$this->_current_field] = $this->obj->input->xss_clean($str);
695 }
696
697 // --------------------------------------------------------------------
698
699 /**
700 * Convert PHP tags to entities
701 *
702 * @access public
703 * @param string
704 * @return string
705 */
706 function encode_php_tags($str)
707 {
708 $_POST[$this->_current_field] = str_replace(array('<?php', '<?PHP', '<?', '?>'), array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
709 }
710
711}
712// END Validation Class
713?>