blob: 065e7a2d545bfb5be7c4b83e5585b665a03cf357 [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
16// ------------------------------------------------------------------------
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
admindac65762006-09-17 18:05:43 +0000190 if ( ! in_array('required', $ex) 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 {
209 if (in_array('isset', $ex) OR in_array('required', $ex))
210 {
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...
271 if ( ! in_array('required', $ex) 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
522 * @param string
523 * @return bool
524 */
525 function numeric($str)
526 {
admin1cf89aa2006-09-03 18:24:39 +0000527 return ( ! is_numeric($str)) ? FALSE : TRUE;
adminb0dd10f2006-08-25 17:25:49 +0000528 }
529
530 // --------------------------------------------------------------------
531
532 /**
533 * Set Select
534 *
535 * Enables pull-down lists to be set to the value the user
536 * selected in the event of an error
537 *
538 * @access public
539 * @param string
540 * @param string
541 * @return string
542 */
543 function set_select($field = '', $value = '')
544 {
545 if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
546 {
547 return '';
548 }
549
550 if ($_POST[$field] == $value)
551 {
552 return ' selected="selected"';
553 }
554 }
555
556 // --------------------------------------------------------------------
557
558 /**
559 * Set Radio
560 *
561 * Enables radio buttons to be set to the value the user
562 * selected in the event of an error
563 *
564 * @access public
565 * @param string
566 * @param string
567 * @return string
568 */
569 function set_radio($field = '', $value = '')
570 {
571 if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
572 {
573 return '';
574 }
575
576 if ($_POST[$field] == $value)
577 {
578 return ' checked="checked"';
579 }
580 }
581
582 // --------------------------------------------------------------------
583
584 /**
585 * Set Checkbox
586 *
587 * Enables checkboxes to be set to the value the user
588 * selected in the event of an error
589 *
590 * @access public
591 * @param string
592 * @param string
593 * @return string
594 */
595 function set_checkbox($field = '', $value = '')
596 {
597 if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
598 {
599 return '';
600 }
601
602 if ($_POST[$field] == $value)
603 {
604 return ' checked="checked"';
605 }
606 }
607
608 // --------------------------------------------------------------------
609
610 /**
611 * Prep data for form
612 *
613 * This function allows HTML to be safely shown in a form.
614 * Special characters are converted.
615 *
616 * @access public
617 * @param string
618 * @return string
619 */
620 function prep_for_form($str = '')
621 {
622 if ($this->_safe_form_data == FALSE OR $str == '')
623 {
624 return $str;
625 }
626
627 return str_replace(array("'", '"', '<', '>'), array("&#39;", "&quot;", '&lt;', '&gt;'), stripslashes($str));
628 }
629
630 // --------------------------------------------------------------------
631
632 /**
633 * Prep URL
634 *
635 * @access public
636 * @param string
637 * @return string
638 */
639 function prep_url($str = '')
640 {
641 if ($str == 'http://' OR $str == '')
642 {
643 $_POST[$this->_current_field] = '';
644 return;
645 }
646
647 if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')
648 {
649 $str = 'http://'.$str;
650 }
651
652 $_POST[$this->_current_field] = $str;
653 }
654
655 // --------------------------------------------------------------------
656
657 /**
658 * Strip Image Tags
659 *
660 * @access public
661 * @param string
662 * @return string
663 */
664 function strip_image_tags($str)
665 {
666 $_POST[$this->_current_field] = $this->input->strip_image_tags($str);
667 }
668
669 // --------------------------------------------------------------------
670
671 /**
672 * XSS Clean
673 *
674 * @access public
675 * @param string
676 * @return string
677 */
678 function xss_clean($str)
679 {
680 $_POST[$this->_current_field] = $this->obj->input->xss_clean($str);
681 }
682
683 // --------------------------------------------------------------------
684
685 /**
686 * Convert PHP tags to entities
687 *
688 * @access public
689 * @param string
690 * @return string
691 */
692 function encode_php_tags($str)
693 {
694 $_POST[$this->_current_field] = str_replace(array('<?php', '<?PHP', '<?', '?>'), array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
695 }
696
697}
698// END Validation Class
699?>