blob: e4fd366986f52eb434d0f5470ed065360f33060b [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 {
243
244 // Is the rule a callback?
245 $callback = FALSE;
246 if (substr($rule, 0, 9) == 'callback_')
247 {
248 $rule = substr($rule, 9);
249 $callback = TRUE;
250 }
251
252 // Strip the parameter (if exists) from the rule
253 // Rules can contain a parameter: max_length[5]
254 $param = FALSE;
admin141808a2006-08-27 01:52:51 +0000255 if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))
adminb0dd10f2006-08-25 17:25:49 +0000256 {
admin141808a2006-08-27 01:52:51 +0000257 $rule = $match[1];
258 $param = $match[2];
adminb0dd10f2006-08-25 17:25:49 +0000259 }
admin141808a2006-08-27 01:52:51 +0000260
adminb0dd10f2006-08-25 17:25:49 +0000261 // Call the function that corresponds to the rule
262 if ($callback === TRUE)
263 {
264 if ( ! method_exists($this->obj, $rule))
265 {
266 continue;
267 }
268
269 $result = $this->obj->$rule($_POST[$field], $param);
270 }
271 else
272 {
273 if ( ! method_exists($this, $rule))
274 {
275 /*
276 * Run the native PHP function if called for
277 *
278 * If our own wrapper function doesn't exist we see
279 * if a native PHP function does. Users can use
280 * any native PHP function call that has one param.
281 */
282 if (function_exists($rule))
283 {
284 $_POST[$field] = $rule($_POST[$field]);
285 $this->$field = $_POST[$field];
286 }
287
288 continue;
289 }
290
291 $result = $this->$rule($_POST[$field], $param);
292 }
293
294 // Did the rule test negatively? If so, grab the error.
295 if ($result === FALSE)
296 {
297 if ( ! isset($this->_error_messages[$rule]))
298 {
299 if (FALSE === ($line = $this->obj->lang->line($rule)))
300 {
301 $line = 'Unable to access an error message corresponding to your field name.';
302 }
303 }
304 else
305 {
306 $line = $this->_error_messages[$rule];;
307 }
308
309 // Build the error message
310 $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
311 $mparam = ( ! isset($this->_fields[$param])) ? $param : $this->_fields[$param];
312 $message = sprintf($line, $mfield, $mparam);
313
314 // Set the error variable. Example: $this->username_error
315 $error = $field.'_error';
316 $this->$error = $this->_error_prefix.$message.$this->_error_suffix;
317
318 // Add the error to the error array
319 $this->_error_array[] = $message;
320 continue 2;
321 }
322 }
323 }
324
325 $total_errors = count($this->_error_array);
326
327 /*
328 * Recompile the class variables
329 *
330 * If any prepping functions were called the $_POST data
331 * might now be different then the corresponding class
332 * variables so we'll set them anew.
333 */
334 if ($total_errors > 0)
335 {
336 $this->_safe_form_data = TRUE;
337 }
338
339 $this->set_fields();
340
341 // Did we end up with any errors?
342 if ($total_errors == 0)
343 {
344 return TRUE;
345 }
346
347 // Generate the error string
348 foreach ($this->_error_array as $val)
349 {
350 $this->error_string .= $this->_error_prefix.$val.$this->_error_suffix."\n";
351 }
352
353 return FALSE;
354 }
355
356 // --------------------------------------------------------------------
357
358 /**
359 * Required
360 *
361 * @access public
362 * @param string
363 * @return bool
364 */
365 function required($str)
366 {
367 if ( ! is_array($str))
368 {
369 return (trim($str) == '') ? FALSE : TRUE;
370 }
371 else
372 {
373 return ( ! empty($str));
374 }
375 }
376
377 // --------------------------------------------------------------------
378
379 /**
380 * Match one field to another
381 *
382 * @access public
383 * @param string
384 * @return bool
385 */
386 function matches($str, $field)
387 {
388 if ( ! isset($_POST[$field]))
389 {
390 return FALSE;
391 }
392
393 return ($str !== $_POST[$field]) ? FALSE : TRUE;
394 }
395
396 // --------------------------------------------------------------------
397
398 /**
399 * Minimum Length
400 *
401 * @access public
402 * @param string
403 * @return bool
404 */
405 function min_length($str, $val)
406 {
admin1cf89aa2006-09-03 18:24:39 +0000407 if ( ! is_numeric($val))
adminb0dd10f2006-08-25 17:25:49 +0000408 {
409 return FALSE;
410 }
411
412 return (strlen($str) < $val) ? FALSE : TRUE;
413 }
414
415 // --------------------------------------------------------------------
416
417 /**
418 * Max Length
419 *
420 * @access public
421 * @param string
422 * @return bool
423 */
424 function max_length($str, $val)
425 {
admin1cf89aa2006-09-03 18:24:39 +0000426 if ( ! is_numeric($val))
adminb0dd10f2006-08-25 17:25:49 +0000427 {
428 return FALSE;
429 }
430
431 return (strlen($str) > $val) ? FALSE : TRUE;
432 }
433
434 // --------------------------------------------------------------------
435
436 /**
437 * Exact Length
438 *
439 * @access public
440 * @param string
441 * @return bool
442 */
443 function exact_length($str, $val)
444 {
admin1cf89aa2006-09-03 18:24:39 +0000445 if ( ! is_numeric($val))
adminb0dd10f2006-08-25 17:25:49 +0000446 {
447 return FALSE;
448 }
449
450 return (strlen($str) != $val) ? FALSE : TRUE;
451 }
452
453 // --------------------------------------------------------------------
454
455 /**
456 * Valid Email
457 *
458 * @access public
459 * @param string
460 * @return bool
461 */
462 function valid_email($str)
463 {
464 return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
465 }
466
467 // --------------------------------------------------------------------
468
469 /**
470 * Alpha
471 *
472 * @access public
473 * @param string
474 * @return bool
475 */
476 function alpha($str)
477 {
478 return ( ! preg_match("/^([-a-z])+$/i", $str)) ? FALSE : TRUE;
479 }
480
481 // --------------------------------------------------------------------
482
483 /**
484 * Alpha-numeric
485 *
486 * @access public
487 * @param string
488 * @return bool
489 */
490 function alpha_numeric($str)
491 {
492 return ( ! preg_match("/^([-a-z0-9])+$/i", $str)) ? FALSE : TRUE;
493 }
494
495 // --------------------------------------------------------------------
496
497 /**
498 * Alpha-numeric with underscores and dashes
499 *
500 * @access public
501 * @param string
502 * @return bool
503 */
504 function alpha_dash($str)
505 {
506 return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;
507 }
508
509 // --------------------------------------------------------------------
510
511 /**
512 * Numeric
513 *
514 * @access public
515 * @param string
516 * @return bool
517 */
518 function numeric($str)
519 {
admin1cf89aa2006-09-03 18:24:39 +0000520 return ( ! is_numeric($str)) ? FALSE : TRUE;
adminb0dd10f2006-08-25 17:25:49 +0000521 }
522
523 // --------------------------------------------------------------------
524
525 /**
526 * Set Select
527 *
528 * Enables pull-down lists to be set to the value the user
529 * selected in the event of an error
530 *
531 * @access public
532 * @param string
533 * @param string
534 * @return string
535 */
536 function set_select($field = '', $value = '')
537 {
538 if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
539 {
540 return '';
541 }
542
543 if ($_POST[$field] == $value)
544 {
545 return ' selected="selected"';
546 }
547 }
548
549 // --------------------------------------------------------------------
550
551 /**
552 * Set Radio
553 *
554 * Enables radio buttons 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_radio($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 ' checked="checked"';
572 }
573 }
574
575 // --------------------------------------------------------------------
576
577 /**
578 * Set Checkbox
579 *
580 * Enables checkboxes 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_checkbox($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 * Prep data for form
605 *
606 * This function allows HTML to be safely shown in a form.
607 * Special characters are converted.
608 *
609 * @access public
610 * @param string
611 * @return string
612 */
613 function prep_for_form($str = '')
614 {
615 if ($this->_safe_form_data == FALSE OR $str == '')
616 {
617 return $str;
618 }
619
620 return str_replace(array("'", '"', '<', '>'), array("&#39;", "&quot;", '&lt;', '&gt;'), stripslashes($str));
621 }
622
623 // --------------------------------------------------------------------
624
625 /**
626 * Prep URL
627 *
628 * @access public
629 * @param string
630 * @return string
631 */
632 function prep_url($str = '')
633 {
634 if ($str == 'http://' OR $str == '')
635 {
636 $_POST[$this->_current_field] = '';
637 return;
638 }
639
640 if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')
641 {
642 $str = 'http://'.$str;
643 }
644
645 $_POST[$this->_current_field] = $str;
646 }
647
648 // --------------------------------------------------------------------
649
650 /**
651 * Strip Image Tags
652 *
653 * @access public
654 * @param string
655 * @return string
656 */
657 function strip_image_tags($str)
658 {
659 $_POST[$this->_current_field] = $this->input->strip_image_tags($str);
660 }
661
662 // --------------------------------------------------------------------
663
664 /**
665 * XSS Clean
666 *
667 * @access public
668 * @param string
669 * @return string
670 */
671 function xss_clean($str)
672 {
673 $_POST[$this->_current_field] = $this->obj->input->xss_clean($str);
674 }
675
676 // --------------------------------------------------------------------
677
678 /**
679 * Convert PHP tags to entities
680 *
681 * @access public
682 * @param string
683 * @return string
684 */
685 function encode_php_tags($str)
686 {
687 $_POST[$this->_current_field] = str_replace(array('<?php', '<?PHP', '<?', '?>'), array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
688 }
689
690}
691// END Validation Class
692?>