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