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