blob: d9d92f0ad7695c6796cd893402dd841a75a4d855 [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02005 * An open source application development framework for PHP
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +02007 * This content is released under the MIT License (MIT)
Eric Barnescccde962011-12-04 00:01:17 -05008 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02009 * Copyright (c) 2014 - 2015, British Columbia Institute of Technology
Eric Barnescccde962011-12-04 00:01:17 -050010 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020011 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
Derek Jonesf4a4bd82011-10-20 12:18:42 -050017 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020018 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 *
29 * @package CodeIgniter
30 * @author EllisLab Dev Team
darwinel871754a2014-02-11 17:34:57 +010031 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
Andrey Andreevfe9309d2015-01-09 17:48:58 +020032 * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020033 * @license http://opensource.org/licenses/MIT MIT License
34 * @link http://codeigniter.com
35 * @since Version 1.0.0
Derek Allard2067d1a2008-11-13 22:59:24 +000036 * @filesource
37 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020038defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000039
Derek Allard2067d1a2008-11-13 22:59:24 +000040/**
41 * Form Validation Class
42 *
43 * @package CodeIgniter
44 * @subpackage Libraries
45 * @category Validation
Derek Jonesf4a4bd82011-10-20 12:18:42 -050046 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000047 * @link http://codeigniter.com/user_guide/libraries/form_validation.html
48 */
49class CI_Form_validation {
Barry Mienydd671972010-10-04 16:33:58 +020050
Timothy Warren0688ac92012-04-20 10:25:04 -040051 /**
52 * Reference to the CodeIgniter instance
53 *
54 * @var object
55 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +010056 protected $CI;
Derek Allard2067d1a2008-11-13 22:59:24 +000057
Timothy Warren0688ac92012-04-20 10:25:04 -040058 /**
59 * Validation data for the current form submission
60 *
61 * @var array
62 */
Andrey Andreev56454792012-05-17 14:32:19 +030063 protected $_field_data = array();
64
Timothy Warren0688ac92012-04-20 10:25:04 -040065 /**
66 * Validation rules for the current form
67 *
68 * @var array
69 */
Andrey Andreev56454792012-05-17 14:32:19 +030070 protected $_config_rules = array();
71
Timothy Warren0688ac92012-04-20 10:25:04 -040072 /**
73 * Array of validation errors
74 *
75 * @var array
76 */
Andrey Andreev78f55772012-04-03 19:59:08 +030077 protected $_error_array = array();
Andrey Andreev56454792012-05-17 14:32:19 +030078
Timothy Warren0688ac92012-04-20 10:25:04 -040079 /**
80 * Array of custom error messages
81 *
82 * @var array
83 */
Andrey Andreev78f55772012-04-03 19:59:08 +030084 protected $_error_messages = array();
Andrey Andreev56454792012-05-17 14:32:19 +030085
Timothy Warren0688ac92012-04-20 10:25:04 -040086 /**
87 * Start tag for error wrapping
88 *
89 * @var string
90 */
Andrey Andreev78f55772012-04-03 19:59:08 +030091 protected $_error_prefix = '<p>';
Andrey Andreev56454792012-05-17 14:32:19 +030092
Timothy Warren0688ac92012-04-20 10:25:04 -040093 /**
94 * End tag for error wrapping
Andrey Andreev56454792012-05-17 14:32:19 +030095 *
Timothy Warren0688ac92012-04-20 10:25:04 -040096 * @var string
97 */
Andrey Andreev78f55772012-04-03 19:59:08 +030098 protected $_error_suffix = '</p>';
Andrey Andreev56454792012-05-17 14:32:19 +030099
Timothy Warren0688ac92012-04-20 10:25:04 -0400100 /**
101 * Custom error message
102 *
103 * @var string
104 */
Andrey Andreev78f55772012-04-03 19:59:08 +0300105 protected $error_string = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300106
Timothy Warren0688ac92012-04-20 10:25:04 -0400107 /**
108 * Whether the form data has been validated as safe
109 *
110 * @var bool
111 */
Andrey Andreev78f55772012-04-03 19:59:08 +0300112 protected $_safe_form_data = FALSE;
Andrey Andreev56454792012-05-17 14:32:19 +0300113
Timothy Warren0688ac92012-04-20 10:25:04 -0400114 /**
115 * Custom data to validate
116 *
117 * @var array
118 */
Andrey Andreevcff35802012-11-26 15:49:52 +0200119 public $validation_data = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000120
Timothy Warren0688ac92012-04-20 10:25:04 -0400121 /**
122 * Initialize Form_Validation class
123 *
Andrey Andreev56454792012-05-17 14:32:19 +0300124 * @param array $rules
125 * @return void
Timothy Warren0688ac92012-04-20 10:25:04 -0400126 */
Greg Akera9263282010-11-10 15:26:43 -0600127 public function __construct($rules = array())
Barry Mienydd671972010-10-04 16:33:58 +0200128 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000129 $this->CI =& get_instance();
Barry Mienydd671972010-10-04 16:33:58 +0200130
Mike Funk326a5e72012-02-24 10:06:28 -0500131 // applies delimiters set in config file.
Mike Funk7f42d062012-03-08 09:00:57 -0500132 if (isset($rules['error_prefix']))
133 {
134 $this->_error_prefix = $rules['error_prefix'];
135 unset($rules['error_prefix']);
136 }
137 if (isset($rules['error_suffix']))
138 {
139 $this->_error_suffix = $rules['error_suffix'];
140 unset($rules['error_suffix']);
141 }
Andrey Andreev31cf46e2012-03-20 15:48:00 +0200142
Derek Allard2067d1a2008-11-13 22:59:24 +0000143 // Validation rules can be stored in a config file.
144 $this->_config_rules = $rules;
Barry Mienydd671972010-10-04 16:33:58 +0200145
Derek Allard2067d1a2008-11-13 22:59:24 +0000146 // Automatically load the form helper
147 $this->CI->load->helper('form');
148
Andrey Andreev901573c2012-01-11 01:40:48 +0200149 log_message('debug', 'Form Validation Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000150 }
Barry Mienydd671972010-10-04 16:33:58 +0200151
Derek Allard2067d1a2008-11-13 22:59:24 +0000152 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200153
Derek Allard2067d1a2008-11-13 22:59:24 +0000154 /**
155 * Set Rules
156 *
157 * This function takes an array of field names and validation
Andrey Andreev4b90a372014-03-10 10:24:24 +0200158 * rules as input, any custom error messages, validates the info,
Ahmedul Haque Abid42b40002014-01-09 01:10:25 +0600159 * and stores it
Derek Allard2067d1a2008-11-13 22:59:24 +0000160 *
Timothy Warren0688ac92012-04-20 10:25:04 -0400161 * @param mixed $field
162 * @param string $label
163 * @param mixed $rules
Ahmedul Haque Abid0742fad2014-01-09 07:51:10 +0600164 * @param array $errors
Andrew Podner4296a652012-12-17 07:51:15 -0500165 * @return CI_Form_validation
Derek Allard2067d1a2008-11-13 22:59:24 +0000166 */
Andrey Andreev4b90a372014-03-10 10:24:24 +0200167 public function set_rules($field, $label = '', $rules = array(), $errors = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000168 {
169 // No reason to set rules if we have no POST data
JonoB099c4782012-03-04 14:37:30 +0000170 // or a validation array has not been specified
Andrey Andreev3b2c5082012-03-07 22:49:24 +0200171 if ($this->CI->input->method() !== 'post' && empty($this->validation_data))
Derek Allard2067d1a2008-11-13 22:59:24 +0000172 {
Greg Aker9f9af602010-11-10 15:41:51 -0600173 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000174 }
Barry Mienydd671972010-10-04 16:33:58 +0200175
tiyowanc2acb232012-03-14 21:24:00 +0400176 // If an array was passed via the first parameter instead of individual string
Derek Allard2067d1a2008-11-13 22:59:24 +0000177 // values we cycle through it and recursively call this function.
178 if (is_array($field))
179 {
180 foreach ($field as $row)
181 {
182 // Houston, we have a problem...
Andrey Andreev78f55772012-04-03 19:59:08 +0300183 if ( ! isset($row['field'], $row['rules']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000184 {
185 continue;
186 }
187
188 // If the field label wasn't passed we use the field name
Andrey Andreev78f55772012-04-03 19:59:08 +0300189 $label = isset($row['label']) ? $row['label'] : $row['field'];
Derek Allard2067d1a2008-11-13 22:59:24 +0000190
Ahmedul Haque Abid42b40002014-01-09 01:10:25 +0600191 // Add the custom error message array
Ahmedul Haque Abidea294882014-01-09 16:01:31 +0600192 $errors = (isset($row['errors']) && is_array($row['errors'])) ? $row['errors'] : array();
Ahmedul Haque Abid42b40002014-01-09 01:10:25 +0600193
Derek Allard2067d1a2008-11-13 22:59:24 +0000194 // Here we go!
Ahmedul Haque Abidbc1cbad2014-01-09 07:53:34 +0600195 $this->set_rules($row['field'], $label, $row['rules'], $errors);
Derek Allard2067d1a2008-11-13 22:59:24 +0000196 }
Andrey Andreev78f55772012-04-03 19:59:08 +0300197
Greg Aker9f9af602010-11-10 15:41:51 -0600198 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000199 }
Barry Mienydd671972010-10-04 16:33:58 +0200200
Derek Allard2067d1a2008-11-13 22:59:24 +0000201 // No fields? Nothing to do...
Andrey Andreev4b90a372014-03-10 10:24:24 +0200202 if ( ! is_string($field) OR $field === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000203 {
Greg Aker9f9af602010-11-10 15:41:51 -0600204 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000205 }
Andrey Andreev4b90a372014-03-10 10:24:24 +0200206 elseif ( ! is_array($rules))
207 {
208 // BC: Convert pipe-separated rules string to an array
209 if (is_string($rules))
210 {
211 $rules = explode('|', $rules);
212 }
213 else
214 {
215 return $this;
216 }
217 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000218
219 // If the field label wasn't passed we use the field name
Alex Bilbied261b1e2012-06-02 11:12:16 +0100220 $label = ($label === '') ? $field : $label;
Derek Allard2067d1a2008-11-13 22:59:24 +0000221
Andrey Andreevfde170c2014-03-10 19:55:11 +0200222 $indexes = array();
223
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200224 // Is the field name an array? If it is an array, we break it apart
Barry Mienydd671972010-10-04 16:33:58 +0200225 // into its components so that we can fetch the corresponding POST data later
Andrey Andreev4b90a372014-03-10 10:24:24 +0200226 if (($is_array = (bool) preg_match_all('/\[(.*?)\]/', $field, $matches)) === TRUE)
Barry Mienydd671972010-10-04 16:33:58 +0200227 {
Andrey Andreev7a7ad782012-11-12 17:21:01 +0200228 sscanf($field, '%[^[][', $indexes[0]);
Derek Allard2067d1a2008-11-13 22:59:24 +0000229
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200230 for ($i = 0, $c = count($matches[0]); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000231 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100232 if ($matches[1][$i] !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000233 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200234 $indexes[] = $matches[1][$i];
Derek Allard2067d1a2008-11-13 22:59:24 +0000235 }
236 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000237 }
Barry Mienydd671972010-10-04 16:33:58 +0200238
239 // Build our master array
Derek Allard2067d1a2008-11-13 22:59:24 +0000240 $this->_field_data[$field] = array(
Andrey Andreev56454792012-05-17 14:32:19 +0300241 'field' => $field,
242 'label' => $label,
243 'rules' => $rules,
Ahmedul Haque Abid7945d302014-01-09 16:50:23 +0600244 'errors' => $errors,
Andrey Andreev56454792012-05-17 14:32:19 +0300245 'is_array' => $is_array,
246 'keys' => $indexes,
247 'postdata' => NULL,
248 'error' => ''
Phil Sturgeonef112c02011-02-07 13:01:47 +0000249 );
Greg Aker9f9af602010-11-10 15:41:51 -0600250
251 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000252 }
253
254 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200255
Derek Allard2067d1a2008-11-13 22:59:24 +0000256 /**
JonoB099c4782012-03-04 14:37:30 +0000257 * By default, form validation uses the $_POST array to validate
Andrey Andreevc8da4fe2012-03-04 19:20:33 +0200258 *
JonoB099c4782012-03-04 14:37:30 +0000259 * If an array is set through this method, then this array will
260 * be used instead of the $_POST array
Andrey Andreev3b2c5082012-03-07 22:49:24 +0200261 *
262 * Note that if you are validating multiple arrays, then the
263 * reset_validation() function should be called after validating
JonoB883f80f2012-03-05 09:51:27 +0000264 * each array due to the limitations of CI's singleton
Andrey Andreevc8da4fe2012-03-04 19:20:33 +0200265 *
266 * @param array $data
Andrey Andreeva89c1da2014-02-08 19:03:35 +0200267 * @return CI_Form_validation
JonoB099c4782012-03-04 14:37:30 +0000268 */
Andrey Andreeva4712f52014-01-06 11:25:46 +0200269 public function set_data(array $data)
JonoB099c4782012-03-04 14:37:30 +0000270 {
Andrey Andreeva4712f52014-01-06 11:25:46 +0200271 if ( ! empty($data))
JonoB099c4782012-03-04 14:37:30 +0000272 {
Andrey Andreevc8da4fe2012-03-04 19:20:33 +0200273 $this->validation_data = $data;
JonoB099c4782012-03-04 14:37:30 +0000274 }
Andrey Andreeva89c1da2014-02-08 19:03:35 +0200275
276 return $this;
JonoB099c4782012-03-04 14:37:30 +0000277 }
Andrey Andreevc8da4fe2012-03-04 19:20:33 +0200278
JonoB099c4782012-03-04 14:37:30 +0000279 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000280
281 /**
282 * Set Error Message
283 *
Andrey Andreev78f55772012-04-03 19:59:08 +0300284 * Lets users set their own error messages on the fly. Note:
285 * The key name has to match the function name that it corresponds to.
Derek Allard2067d1a2008-11-13 22:59:24 +0000286 *
Andrey Andreev78f55772012-04-03 19:59:08 +0300287 * @param array
Derek Allard2067d1a2008-11-13 22:59:24 +0000288 * @param string
Andrew Podner4296a652012-12-17 07:51:15 -0500289 * @return CI_Form_validation
Derek Allard2067d1a2008-11-13 22:59:24 +0000290 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100291 public function set_message($lang, $val = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000292 {
293 if ( ! is_array($lang))
294 {
295 $lang = array($lang => $val);
296 }
Barry Mienydd671972010-10-04 16:33:58 +0200297
Derek Allard2067d1a2008-11-13 22:59:24 +0000298 $this->_error_messages = array_merge($this->_error_messages, $lang);
Greg Aker9f9af602010-11-10 15:41:51 -0600299 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000300 }
Barry Mienydd671972010-10-04 16:33:58 +0200301
Derek Allard2067d1a2008-11-13 22:59:24 +0000302 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200303
Derek Allard2067d1a2008-11-13 22:59:24 +0000304 /**
305 * Set The Error Delimiter
306 *
307 * Permits a prefix/suffix to be added to each error message
308 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000309 * @param string
310 * @param string
Andrew Podner4296a652012-12-17 07:51:15 -0500311 * @return CI_Form_validation
Barry Mienydd671972010-10-04 16:33:58 +0200312 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100313 public function set_error_delimiters($prefix = '<p>', $suffix = '</p>')
Derek Allard2067d1a2008-11-13 22:59:24 +0000314 {
315 $this->_error_prefix = $prefix;
316 $this->_error_suffix = $suffix;
Greg Aker9f9af602010-11-10 15:41:51 -0600317 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000318 }
319
320 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200321
Derek Allard2067d1a2008-11-13 22:59:24 +0000322 /**
323 * Get Error Message
324 *
325 * Gets the error message associated with a particular field
326 *
Andrey Andreeva4712f52014-01-06 11:25:46 +0200327 * @param string $field Field name
328 * @param string $prefix HTML start tag
Andrey Andreev868301a2014-01-06 12:29:50 +0200329 * @param string $suffix HTML end tag
Andrey Andreev78f55772012-04-03 19:59:08 +0300330 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200331 */
Andrey Andreeva4712f52014-01-06 11:25:46 +0200332 public function error($field, $prefix = '', $suffix = '')
Barry Mienydd671972010-10-04 16:33:58 +0200333 {
Andrey Andreev78f55772012-04-03 19:59:08 +0300334 if (empty($this->_field_data[$field]['error']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000335 {
336 return '';
337 }
Barry Mienydd671972010-10-04 16:33:58 +0200338
Alex Bilbied261b1e2012-06-02 11:12:16 +0100339 if ($prefix === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000340 {
341 $prefix = $this->_error_prefix;
342 }
343
Alex Bilbied261b1e2012-06-02 11:12:16 +0100344 if ($suffix === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000345 {
346 $suffix = $this->_error_suffix;
347 }
348
349 return $prefix.$this->_field_data[$field]['error'].$suffix;
350 }
351
352 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200353
Derek Allard2067d1a2008-11-13 22:59:24 +0000354 /**
Michiel Vugteveen676a0dd2012-03-02 10:10:34 +0100355 * Get Array of Error Messages
356 *
357 * Returns the error messages as an array
358 *
359 * @return array
360 */
361 public function error_array()
362 {
363 return $this->_error_array;
364 }
365
366 // --------------------------------------------------------------------
367
368 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000369 * Error String
370 *
371 * Returns the error messages as a string, wrapped in the error delimiters
372 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000373 * @param string
374 * @param string
Andrey Andreev78f55772012-04-03 19:59:08 +0300375 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200376 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100377 public function error_string($prefix = '', $suffix = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000378 {
vlakoff35672462013-02-15 01:36:04 +0100379 // No errors, validation passes!
Derek Allard2067d1a2008-11-13 22:59:24 +0000380 if (count($this->_error_array) === 0)
381 {
382 return '';
383 }
Barry Mienydd671972010-10-04 16:33:58 +0200384
Alex Bilbied261b1e2012-06-02 11:12:16 +0100385 if ($prefix === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000386 {
387 $prefix = $this->_error_prefix;
388 }
389
Alex Bilbied261b1e2012-06-02 11:12:16 +0100390 if ($suffix === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000391 {
392 $suffix = $this->_error_suffix;
393 }
Barry Mienydd671972010-10-04 16:33:58 +0200394
Derek Allard2067d1a2008-11-13 22:59:24 +0000395 // Generate the error string
396 $str = '';
397 foreach ($this->_error_array as $val)
398 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100399 if ($val !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000400 {
401 $str .= $prefix.$val.$suffix."\n";
402 }
403 }
Barry Mienydd671972010-10-04 16:33:58 +0200404
Derek Allard2067d1a2008-11-13 22:59:24 +0000405 return $str;
406 }
407
408 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200409
Derek Allard2067d1a2008-11-13 22:59:24 +0000410 /**
411 * Run the Validator
412 *
413 * This function does all the work.
414 *
Timothy Warren0688ac92012-04-20 10:25:04 -0400415 * @param string $group
Derek Allard2067d1a2008-11-13 22:59:24 +0000416 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +0200417 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100418 public function run($group = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000419 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500420 // Do we even have any data to process? Mm?
Andrey Andreev78f55772012-04-03 19:59:08 +0300421 $validation_array = empty($this->validation_data) ? $_POST : $this->validation_data;
JonoB099c4782012-03-04 14:37:30 +0000422 if (count($validation_array) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000423 {
424 return FALSE;
425 }
Barry Mienydd671972010-10-04 16:33:58 +0200426
Derek Allard2067d1a2008-11-13 22:59:24 +0000427 // Does the _field_data array containing the validation rules exist?
428 // If not, we look to see if they were assigned via a config file
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200429 if (count($this->_field_data) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000430 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500431 // No validation rules? We're done...
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200432 if (count($this->_config_rules) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000433 {
434 return FALSE;
435 }
Barry Mienydd671972010-10-04 16:33:58 +0200436
Andrey Andreev3b2803e2014-01-07 14:46:38 +0200437 if (empty($group))
438 {
439 // Is there a validation rule for the particular URI being accessed?
440 $group = trim($this->CI->uri->ruri_string(), '/');
441 isset($this->_config_rules[$group]) OR $group = $this->CI->router->class.'/'.$this->CI->router->method;
442 }
Barry Mienydd671972010-10-04 16:33:58 +0200443
Andrey Andreev3b2803e2014-01-07 14:46:38 +0200444 $this->set_rules(isset($this->_config_rules[$group]) ? $this->_config_rules[$group] : $this->_config_rules);
Barry Mienydd671972010-10-04 16:33:58 +0200445
Andrey Andreev901573c2012-01-11 01:40:48 +0200446 // Were we able to set the rules correctly?
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200447 if (count($this->_field_data) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000448 {
Andrey Andreev901573c2012-01-11 01:40:48 +0200449 log_message('debug', 'Unable to find validation rules');
Derek Allard2067d1a2008-11-13 22:59:24 +0000450 return FALSE;
451 }
452 }
Barry Mienydd671972010-10-04 16:33:58 +0200453
Derek Allard2067d1a2008-11-13 22:59:24 +0000454 // Load the language file containing error messages
455 $this->CI->lang->load('form_validation');
Barry Mienydd671972010-10-04 16:33:58 +0200456
Andrey Andreev751f2472012-11-03 18:26:27 +0200457 // Cycle through the rules for each field and match the corresponding $validation_data item
Derek Allard2067d1a2008-11-13 22:59:24 +0000458 foreach ($this->_field_data as $field => $row)
Barry Mienydd671972010-10-04 16:33:58 +0200459 {
Andrey Andreev751f2472012-11-03 18:26:27 +0200460 // Fetch the data from the validation_data array item and cache it in the _field_data array.
Derek Allard2067d1a2008-11-13 22:59:24 +0000461 // Depending on whether the field name is an array or a string will determine where we get it from.
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200462 if ($row['is_array'] === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000463 {
JonoB099c4782012-03-04 14:37:30 +0000464 $this->_field_data[$field]['postdata'] = $this->_reduce_array($validation_array, $row['keys']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000465 }
Andrey Andreevfff6c2a2012-05-13 22:15:23 +0300466 elseif (isset($validation_array[$field]) && $validation_array[$field] !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000467 {
Andrey Andreev78f55772012-04-03 19:59:08 +0300468 $this->_field_data[$field]['postdata'] = $validation_array[$field];
Derek Allard2067d1a2008-11-13 22:59:24 +0000469 }
Andrey Andreev751f2472012-11-03 18:26:27 +0200470 }
Barry Mienydd671972010-10-04 16:33:58 +0200471
Andrey Andreev751f2472012-11-03 18:26:27 +0200472 // Execute validation rules
473 // Note: A second foreach (for now) is required in order to avoid false-positives
474 // for rules like 'matches', which correlate to other validation fields.
475 foreach ($this->_field_data as $field => $row)
476 {
Andrey Andreev3d9cec92012-07-08 21:50:19 +0300477 // Don't try to validate if we have no rules set
478 if (empty($row['rules']))
479 {
480 continue;
481 }
Barry Mienydd671972010-10-04 16:33:58 +0200482
Andrey Andreev4b90a372014-03-10 10:24:24 +0200483 $this->_execute($row, $row['rules'], $this->_field_data[$field]['postdata']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000484 }
485
486 // Did we end up with any errors?
487 $total_errors = count($this->_error_array);
Derek Allard2067d1a2008-11-13 22:59:24 +0000488 if ($total_errors > 0)
489 {
490 $this->_safe_form_data = TRUE;
491 }
492
493 // Now we need to re-set the POST data with the new, processed data
494 $this->_reset_post_array();
Barry Mienydd671972010-10-04 16:33:58 +0200495
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200496 return ($total_errors === 0);
Derek Allard2067d1a2008-11-13 22:59:24 +0000497 }
498
499 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200500
Derek Allard2067d1a2008-11-13 22:59:24 +0000501 /**
502 * Traverse a multidimensional $_POST array index until the data is found
503 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000504 * @param array
505 * @param array
Andrey Andreev78f55772012-04-03 19:59:08 +0300506 * @param int
Derek Allard2067d1a2008-11-13 22:59:24 +0000507 * @return mixed
Barry Mienydd671972010-10-04 16:33:58 +0200508 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100509 protected function _reduce_array($array, $keys, $i = 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000510 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200511 if (is_array($array) && isset($keys[$i]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000512 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200513 return isset($array[$keys[$i]]) ? $this->_reduce_array($array[$keys[$i]], $keys, ($i+1)) : NULL;
Derek Allard2067d1a2008-11-13 22:59:24 +0000514 }
Barry Mienydd671972010-10-04 16:33:58 +0200515
Andrey Andreev2d48b4f2012-11-23 17:33:21 +0200516 // NULL must be returned for empty fields
Andrey Andreev44c34632012-11-23 18:46:34 +0200517 return ($array === '') ? NULL : $array;
Derek Allard2067d1a2008-11-13 22:59:24 +0000518 }
519
520 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200521
Derek Allard2067d1a2008-11-13 22:59:24 +0000522 /**
523 * Re-populate the _POST array with our finalized and processed data
524 *
Andrey Andreev6de924c2012-01-20 13:18:18 +0200525 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200526 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100527 protected function _reset_post_array()
Derek Allard2067d1a2008-11-13 22:59:24 +0000528 {
529 foreach ($this->_field_data as $field => $row)
530 {
vlakoff1228fe22013-01-14 01:30:09 +0100531 if ($row['postdata'] !== NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000532 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200533 if ($row['is_array'] === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000534 {
535 if (isset($_POST[$row['field']]))
536 {
Andrey Andreevc2268712013-02-08 22:10:23 +0200537 $_POST[$row['field']] = $row['postdata'];
Derek Allard2067d1a2008-11-13 22:59:24 +0000538 }
539 }
540 else
541 {
Derek Jones63eeae32009-02-10 19:08:56 +0000542 // start with a reference
543 $post_ref =& $_POST;
Barry Mienydd671972010-10-04 16:33:58 +0200544
Derek Jones63eeae32009-02-10 19:08:56 +0000545 // before we assign values, make a reference to the right POST key
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200546 if (count($row['keys']) === 1)
Derek Allard2067d1a2008-11-13 22:59:24 +0000547 {
Derek Jones63eeae32009-02-10 19:08:56 +0000548 $post_ref =& $post_ref[current($row['keys'])];
Derek Allard2067d1a2008-11-13 22:59:24 +0000549 }
550 else
551 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000552 foreach ($row['keys'] as $val)
553 {
Derek Jones63eeae32009-02-10 19:08:56 +0000554 $post_ref =& $post_ref[$val];
Derek Allard2067d1a2008-11-13 22:59:24 +0000555 }
556 }
Derek Jones63eeae32009-02-10 19:08:56 +0000557
Derek Allard2067d1a2008-11-13 22:59:24 +0000558 if (is_array($row['postdata']))
Derek Jones63eeae32009-02-10 19:08:56 +0000559 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000560 $array = array();
561 foreach ($row['postdata'] as $k => $v)
562 {
Andrey Andreevc2268712013-02-08 22:10:23 +0200563 $array[$k] = $v;
Derek Allard2067d1a2008-11-13 22:59:24 +0000564 }
Derek Jones63eeae32009-02-10 19:08:56 +0000565
566 $post_ref = $array;
Derek Allard2067d1a2008-11-13 22:59:24 +0000567 }
568 else
Derek Jones63eeae32009-02-10 19:08:56 +0000569 {
Andrey Andreevc2268712013-02-08 22:10:23 +0200570 $post_ref = $row['postdata'];
Derek Allard2067d1a2008-11-13 22:59:24 +0000571 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000572 }
573 }
574 }
575 }
576
577 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200578
Derek Allard2067d1a2008-11-13 22:59:24 +0000579 /**
580 * Executes the Validation routines
581 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000582 * @param array
583 * @param array
584 * @param mixed
Andrey Andreev78f55772012-04-03 19:59:08 +0300585 * @param int
Derek Allard2067d1a2008-11-13 22:59:24 +0000586 * @return mixed
Barry Mienydd671972010-10-04 16:33:58 +0200587 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100588 protected function _execute($row, $rules, $postdata = NULL, $cycles = 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000589 {
590 // If the $_POST data is an array we will run a recursive call
591 if (is_array($postdata))
Barry Mienydd671972010-10-04 16:33:58 +0200592 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000593 foreach ($postdata as $key => $val)
594 {
Andrey Andreev8d3099d2012-06-21 16:00:20 +0300595 $this->_execute($row, $rules, $val, $key);
Derek Allard2067d1a2008-11-13 22:59:24 +0000596 }
Barry Mienydd671972010-10-04 16:33:58 +0200597
Derek Allard2067d1a2008-11-13 22:59:24 +0000598 return;
599 }
Barry Mienydd671972010-10-04 16:33:58 +0200600
Derek Allard2067d1a2008-11-13 22:59:24 +0000601 // If the field is blank, but NOT required, no further tests are necessary
602 $callback = FALSE;
Hashem Qolami05370bf2013-07-22 01:52:04 +0430603 if ( ! in_array('required', $rules) && ($postdata === NULL OR $postdata === ''))
Derek Allard2067d1a2008-11-13 22:59:24 +0000604 {
605 // Before we bail out, does the rule contain a callback?
Andrey Andreev4b90a372014-03-10 10:24:24 +0200606 foreach ($rules as &$rule)
Derek Allard2067d1a2008-11-13 22:59:24 +0000607 {
Andrey Andreev4b90a372014-03-10 10:24:24 +0200608 if (is_string($rule))
609 {
610 if (strncmp($rule, 'callback_', 9) === 0)
611 {
612 $callback = TRUE;
613 $rules = array(1 => $rule);
614 break;
615 }
616 }
617 elseif (is_callable($rule))
618 {
619 $callback = TRUE;
620 $rules = array(1 => $rule);
621 break;
622 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000623 }
Andrey Andreev4b90a372014-03-10 10:24:24 +0200624
625 if ( ! $callback)
Derek Allard2067d1a2008-11-13 22:59:24 +0000626 {
627 return;
628 }
629 }
630
Derek Allard2067d1a2008-11-13 22:59:24 +0000631 // Isset Test. Typically this rule will only apply to checkboxes.
Andrey Andreev4b90a372014-03-10 10:24:24 +0200632 if (($postdata === NULL OR $postdata === '') && ! $callback)
Derek Allard2067d1a2008-11-13 22:59:24 +0000633 {
634 if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))
635 {
636 // Set the message type
Andrey Andreev78f55772012-04-03 19:59:08 +0300637 $type = in_array('required', $rules) ? 'required' : 'isset';
Barry Mienydd671972010-10-04 16:33:58 +0200638
Ahmedul Haque Abide9b0ccc2014-01-09 15:58:51 +0600639 // Check if a custom message is defined
Ahmedul Haque Abidea294882014-01-09 16:01:31 +0600640 if (isset($this->_field_data[$row['field']]['errors'][$type]))
Ahmedul Haque Abid42b40002014-01-09 01:10:25 +0600641 {
Ahmedul Haque Abidea294882014-01-09 16:01:31 +0600642 $line = $this->_field_data[$row['field']]['errors'][$type];
Ahmedul Haque Abid42b40002014-01-09 01:10:25 +0600643 }
644 elseif (isset($this->_error_messages[$type]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000645 {
646 $line = $this->_error_messages[$type];
647 }
Andrey Andreevd4eec9f2012-12-14 11:07:13 +0200648 elseif (FALSE === ($line = $this->CI->lang->line('form_validation_'.$type))
649 // DEPRECATED support for non-prefixed keys
650 && FALSE === ($line = $this->CI->lang->line($type, FALSE)))
Andrey Andreev56454792012-05-17 14:32:19 +0300651 {
652 $line = 'The field was not set';
653 }
Barry Mienydd671972010-10-04 16:33:58 +0200654
Derek Allard2067d1a2008-11-13 22:59:24 +0000655 // Build the error message
Eric Roberts41cc0902012-01-24 00:59:44 -0600656 $message = $this->_build_error_msg($line, $this->_translate_fieldname($row['label']));
Derek Allard2067d1a2008-11-13 22:59:24 +0000657
658 // Save the error message
659 $this->_field_data[$row['field']]['error'] = $message;
Barry Mienydd671972010-10-04 16:33:58 +0200660
Derek Allard2067d1a2008-11-13 22:59:24 +0000661 if ( ! isset($this->_error_array[$row['field']]))
662 {
663 $this->_error_array[$row['field']] = $message;
664 }
665 }
Barry Mienydd671972010-10-04 16:33:58 +0200666
Derek Allard2067d1a2008-11-13 22:59:24 +0000667 return;
668 }
669
670 // --------------------------------------------------------------------
671
672 // Cycle through each rule and run it
Andrey Andreev78f55772012-04-03 19:59:08 +0300673 foreach ($rules as $rule)
Derek Allard2067d1a2008-11-13 22:59:24 +0000674 {
675 $_in_array = FALSE;
Barry Mienydd671972010-10-04 16:33:58 +0200676
Derek Allard2067d1a2008-11-13 22:59:24 +0000677 // We set the $postdata variable with the current data in our master array so that
678 // each cycle of the loop is dealing with the processed data from the last cycle
Alex Bilbied261b1e2012-06-02 11:12:16 +0100679 if ($row['is_array'] === TRUE && is_array($this->_field_data[$row['field']]['postdata']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000680 {
681 // We shouldn't need this safety, but just in case there isn't an array index
682 // associated with this cycle we'll bail out
683 if ( ! isset($this->_field_data[$row['field']]['postdata'][$cycles]))
684 {
685 continue;
686 }
Barry Mienydd671972010-10-04 16:33:58 +0200687
Derek Allard2067d1a2008-11-13 22:59:24 +0000688 $postdata = $this->_field_data[$row['field']]['postdata'][$cycles];
689 $_in_array = TRUE;
690 }
691 else
692 {
Andrey Andreev6ac51442012-06-18 13:05:17 +0300693 // If we get an array field, but it's not expected - then it is most likely
694 // somebody messing with the form on the client side, so we'll just consider
695 // it an empty field
696 $postdata = is_array($this->_field_data[$row['field']]['postdata'])
Andrey Andreev4b90a372014-03-10 10:24:24 +0200697 ? NULL
698 : $this->_field_data[$row['field']]['postdata'];
Derek Allard2067d1a2008-11-13 22:59:24 +0000699 }
700
Barry Mienydd671972010-10-04 16:33:58 +0200701 // Is the rule a callback?
Andrey Andreev4b90a372014-03-10 10:24:24 +0200702 $callback = $callable = FALSE;
703 if (is_string($rule))
Derek Allard2067d1a2008-11-13 22:59:24 +0000704 {
Andrey Andreev4b90a372014-03-10 10:24:24 +0200705 if (strpos($rule, 'callback_') === 0)
706 {
707 $rule = substr($rule, 9);
708 $callback = TRUE;
709 }
710 }
711 elseif (is_callable($rule))
712 {
713 $callable = TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000714 }
Andrey Andreev60726ef2014-09-08 11:31:48 +0300715 elseif (is_array($rule) && isset($rule[0], $rule[1]) && is_callable($rule[1]))
716 {
717 // We have a "named" callable, so save the name
718 $callable = $rule[0];
719 $rule = $rule[1];
720 }
Barry Mienydd671972010-10-04 16:33:58 +0200721
Derek Allard2067d1a2008-11-13 22:59:24 +0000722 // Strip the parameter (if exists) from the rule
723 // Rules can contain a parameter: max_length[5]
724 $param = FALSE;
Andrey Andreev4b90a372014-03-10 10:24:24 +0200725 if ( ! $callable && preg_match('/(.*?)\[(.*)\]/', $rule, $match))
Derek Allard2067d1a2008-11-13 22:59:24 +0000726 {
Andrey Andreevef758bd2012-11-15 12:24:52 +0200727 $rule = $match[1];
728 $param = $match[2];
Derek Allard2067d1a2008-11-13 22:59:24 +0000729 }
Barry Mienydd671972010-10-04 16:33:58 +0200730
Derek Allard2067d1a2008-11-13 22:59:24 +0000731 // Call the function that corresponds to the rule
Andrey Andreev60726ef2014-09-08 11:31:48 +0300732 if ($callback OR $callable !== FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000733 {
Andrey Andreev4b90a372014-03-10 10:24:24 +0200734 if ($callback)
Barry Mienydd671972010-10-04 16:33:58 +0200735 {
Andrey Andreev4b90a372014-03-10 10:24:24 +0200736 if ( ! method_exists($this->CI, $rule))
737 {
738 log_message('debug', 'Unable to find callback validation rule: '.$rule);
739 $result = FALSE;
740 }
741 else
742 {
743 // Run the function and grab the result
744 $result = $this->CI->$rule($postdata, $param);
745 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000746 }
Andrey Andreev901573c2012-01-11 01:40:48 +0200747 else
748 {
Andrey Andreev4b90a372014-03-10 10:24:24 +0200749 $result = is_array($rule)
Andrey Andreev60726ef2014-09-08 11:31:48 +0300750 ? $rule[0]->{$rule[1]}($postdata)
751 : $rule($postdata);
752
753 // Is $callable set to a rule name?
754 if ($callable !== FALSE)
755 {
756 $rule = $callable;
757 }
Andrey Andreev901573c2012-01-11 01:40:48 +0200758 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000759
760 // Re-assign the result to the master data array
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200761 if ($_in_array === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000762 {
Andrey Andreev78f55772012-04-03 19:59:08 +0300763 $this->_field_data[$row['field']]['postdata'][$cycles] = is_bool($result) ? $postdata : $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000764 }
765 else
766 {
Andrey Andreev78f55772012-04-03 19:59:08 +0300767 $this->_field_data[$row['field']]['postdata'] = is_bool($result) ? $postdata : $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000768 }
Barry Mienydd671972010-10-04 16:33:58 +0200769
Derek Allard2067d1a2008-11-13 22:59:24 +0000770 // If the field isn't required and we just processed a callback we'll move on...
Andrey Andreev6de924c2012-01-20 13:18:18 +0200771 if ( ! in_array('required', $rules, TRUE) && $result !== FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000772 {
Derek Allard4e5cf1c2009-07-06 20:53:41 +0000773 continue;
Derek Allard2067d1a2008-11-13 22:59:24 +0000774 }
775 }
Andrey Andreev78f55772012-04-03 19:59:08 +0300776 elseif ( ! method_exists($this, $rule))
Barry Mienydd671972010-10-04 16:33:58 +0200777 {
Andrey Andreev78f55772012-04-03 19:59:08 +0300778 // If our own wrapper function doesn't exist we see if a native PHP function does.
779 // Users can use any native PHP function call that has one param.
780 if (function_exists($rule))
Derek Allard2067d1a2008-11-13 22:59:24 +0000781 {
Andrey Andreev4b90a372014-03-10 10:24:24 +0200782 // Native PHP functions issue warnings if you pass them more parameters than they use
Andrey Andreev320d37c2012-04-03 20:21:39 +0300783 $result = ($param !== FALSE) ? $rule($postdata, $param) : $rule($postdata);
Barry Mienydd671972010-10-04 16:33:58 +0200784
Andrey Andreev78f55772012-04-03 19:59:08 +0300785 if ($_in_array === TRUE)
786 {
787 $this->_field_data[$row['field']]['postdata'][$cycles] = is_bool($result) ? $postdata : $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000788 }
patwork02404a12011-04-08 15:45:46 +0200789 else
790 {
Andrey Andreevcec2ba52012-04-03 20:26:38 +0300791 $this->_field_data[$row['field']]['postdata'] = is_bool($result) ? $postdata : $result;
patwork02404a12011-04-08 15:45:46 +0200792 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000793 }
Andrey Andreev901573c2012-01-11 01:40:48 +0200794 else
795 {
Andrey Andreevcec2ba52012-04-03 20:26:38 +0300796 log_message('debug', 'Unable to find validation rule: '.$rule);
797 $result = FALSE;
Andrey Andreev901573c2012-01-11 01:40:48 +0200798 }
Andrey Andreev78f55772012-04-03 19:59:08 +0300799 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000800 else
801 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000802 $result = $this->$rule($postdata, $param);
803
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200804 if ($_in_array === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000805 {
Andrey Andreev78f55772012-04-03 19:59:08 +0300806 $this->_field_data[$row['field']]['postdata'][$cycles] = is_bool($result) ? $postdata : $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000807 }
808 else
809 {
Andrey Andreev78f55772012-04-03 19:59:08 +0300810 $this->_field_data[$row['field']]['postdata'] = is_bool($result) ? $postdata : $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000811 }
812 }
Barry Mienydd671972010-10-04 16:33:58 +0200813
Andrey Andreev901573c2012-01-11 01:40:48 +0200814 // Did the rule test negatively? If so, grab the error.
Derek Allard2067d1a2008-11-13 22:59:24 +0000815 if ($result === FALSE)
Barry Mienydd671972010-10-04 16:33:58 +0200816 {
Andrey Andreev60726ef2014-09-08 11:31:48 +0300817 // Callable rules might not have named error messages
Andrey Andreev57f10052014-06-07 12:22:37 +0300818 if ( ! is_string($rule))
Ahmedul Haque Abid42b40002014-01-09 01:10:25 +0600819 {
Andrey Andreev57f10052014-06-07 12:22:37 +0300820 return;
821 }
822
823 // Check if a custom message is defined
824 if (isset($this->_field_data[$row['field']]['errors'][$rule]))
825 {
826 $line = $this->_field_data[$row['field']]['errors'][$rule];
827 }
828 elseif ( ! isset($this->_error_messages[$rule]))
829 {
830 if (FALSE === ($line = $this->CI->lang->line('form_validation_'.$rule))
831 // DEPRECATED support for non-prefixed keys
832 && FALSE === ($line = $this->CI->lang->line($rule, FALSE)))
Derek Allard2067d1a2008-11-13 22:59:24 +0000833 {
Andrey Andreev57f10052014-06-07 12:22:37 +0300834 $line = 'Unable to access an error message corresponding to your field name.';
Barry Mienydd671972010-10-04 16:33:58 +0200835 }
Andrey Andreev57f10052014-06-07 12:22:37 +0300836 }
837 else
838 {
839 $line = $this->_error_messages[$rule];
Derek Allard2067d1a2008-11-13 22:59:24 +0000840 }
Barry Mienydd671972010-10-04 16:33:58 +0200841
Derek Allard2067d1a2008-11-13 22:59:24 +0000842 // Is the parameter we are inserting into the error message the name
Andrey Andreev901573c2012-01-11 01:40:48 +0200843 // of another field? If so we need to grab its "field label"
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200844 if (isset($this->_field_data[$param], $this->_field_data[$param]['label']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000845 {
Pascal Krietec1895832009-10-13 12:56:43 +0000846 $param = $this->_translate_fieldname($this->_field_data[$param]['label']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000847 }
Barry Mienydd671972010-10-04 16:33:58 +0200848
Derek Allard2067d1a2008-11-13 22:59:24 +0000849 // Build the error message
Eric Roberts41cc0902012-01-24 00:59:44 -0600850 $message = $this->_build_error_msg($line, $this->_translate_fieldname($row['label']), $param);
Derek Allard2067d1a2008-11-13 22:59:24 +0000851
852 // Save the error message
853 $this->_field_data[$row['field']]['error'] = $message;
Barry Mienydd671972010-10-04 16:33:58 +0200854
Derek Allard2067d1a2008-11-13 22:59:24 +0000855 if ( ! isset($this->_error_array[$row['field']]))
856 {
857 $this->_error_array[$row['field']] = $message;
858 }
Barry Mienydd671972010-10-04 16:33:58 +0200859
Derek Allard2067d1a2008-11-13 22:59:24 +0000860 return;
861 }
862 }
863 }
864
865 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200866
Derek Allard2067d1a2008-11-13 22:59:24 +0000867 /**
868 * Translate a field name
869 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000870 * @param string the field name
871 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200872 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100873 protected function _translate_fieldname($fieldname)
Derek Allard2067d1a2008-11-13 22:59:24 +0000874 {
875 // Do we need to translate the field name?
876 // We look for the prefix lang: to determine this
Andrey Andreev7a7ad782012-11-12 17:21:01 +0200877 if (sscanf($fieldname, 'lang:%s', $line) === 1)
Derek Allard2067d1a2008-11-13 22:59:24 +0000878 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500879 // Were we able to translate the field name? If not we use $line
Andrey Andreevd4eec9f2012-12-14 11:07:13 +0200880 if (FALSE === ($fieldname = $this->CI->lang->line('form_validation_'.$line))
881 // DEPRECATED support for non-prefixed keys
882 && FALSE === ($fieldname = $this->CI->lang->line($line, FALSE)))
Derek Allard2067d1a2008-11-13 22:59:24 +0000883 {
884 return $line;
885 }
886 }
887
888 return $fieldname;
889 }
890
891 // --------------------------------------------------------------------
Andrey Andreevd4eec9f2012-12-14 11:07:13 +0200892
Eric Roberts41cc0902012-01-24 00:59:44 -0600893 /**
894 * Build an error message using the field and param.
895 *
896 * @param string The error message line
897 * @param string A field's human name
898 * @param mixed A rule's optional parameter
899 * @return string
900 */
901 protected function _build_error_msg($line, $field = '', $param = '')
902 {
903 // Check for %s in the string for legacy support.
Eric Roberts24a13f52012-12-12 07:09:42 -0600904 if (strpos($line, '%s') !== FALSE)
Eric Roberts41cc0902012-01-24 00:59:44 -0600905 {
906 return sprintf($line, $field, $param);
907 }
Andrew Podner4296a652012-12-17 07:51:15 -0500908
Eric Roberts41cc0902012-01-24 00:59:44 -0600909 return str_replace(array('{field}', '{param}'), array($field, $param), $line);
910 }
911
912 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200913
Derek Allard2067d1a2008-11-13 22:59:24 +0000914 /**
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530915 * Checks if the rule is present within the validator
916 *
917 * Permits you to check if a rule is present within the validator
918 *
919 * @param string the field name
920 * @return bool
921 */
922 public function has_rule($field)
923 {
924 return isset($this->_field_data[$field]);
925 }
926
927 // --------------------------------------------------------------------
928
929 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000930 * Get the value from a form
931 *
932 * Permits you to repopulate a form field with the value it was submitted
933 * with, or, if that value doesn't exist, with the default
934 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000935 * @param string the field name
936 * @param string
Andrey Andreev46ac8812012-02-28 14:32:54 +0200937 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200938 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100939 public function set_value($field = '', $default = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000940 {
Andrey Andreev46ac8812012-02-28 14:32:54 +0200941 if ( ! isset($this->_field_data[$field], $this->_field_data[$field]['postdata']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000942 {
943 return $default;
944 }
Barry Mienydd671972010-10-04 16:33:58 +0200945
Phil Sturgeon5c561802011-01-05 16:31:59 +0000946 // If the data is an array output them one at a time.
Greg Aker03abee32011-12-25 00:31:29 -0600947 // E.g: form_input('name[]', set_value('name[]');
Phil Sturgeon5c561802011-01-05 16:31:59 +0000948 if (is_array($this->_field_data[$field]['postdata']))
949 {
950 return array_shift($this->_field_data[$field]['postdata']);
951 }
Phil Sturgeonc3828712011-01-19 12:31:47 +0000952
Derek Allard2067d1a2008-11-13 22:59:24 +0000953 return $this->_field_data[$field]['postdata'];
954 }
Barry Mienydd671972010-10-04 16:33:58 +0200955
Derek Allard2067d1a2008-11-13 22:59:24 +0000956 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200957
Derek Allard2067d1a2008-11-13 22:59:24 +0000958 /**
959 * Set Select
960 *
961 * Enables pull-down lists to be set to the value the user
962 * selected in the event of an error
963 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000964 * @param string
965 * @param string
Timothy Warren0688ac92012-04-20 10:25:04 -0400966 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +0000967 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200968 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100969 public function set_select($field = '', $value = '', $default = FALSE)
Barry Mienydd671972010-10-04 16:33:58 +0200970 {
Andrey Andreev46ac8812012-02-28 14:32:54 +0200971 if ( ! isset($this->_field_data[$field], $this->_field_data[$field]['postdata']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000972 {
Andrey Andreev6de924c2012-01-20 13:18:18 +0200973 return ($default === TRUE && count($this->_field_data) === 0) ? ' selected="selected"' : '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000974 }
Barry Mienydd671972010-10-04 16:33:58 +0200975
Derek Allard2067d1a2008-11-13 22:59:24 +0000976 $field = $this->_field_data[$field]['postdata'];
Andrey Andreeva587a932013-10-23 19:57:46 +0300977 $value = (string) $value;
Derek Allard2067d1a2008-11-13 22:59:24 +0000978 if (is_array($field))
979 {
Andrey Andreeva587a932013-10-23 19:57:46 +0300980 // Note: in_array('', array(0)) returns TRUE, do not use it
981 foreach ($field as &$v)
Derek Allard2067d1a2008-11-13 22:59:24 +0000982 {
Andrey Andreeva587a932013-10-23 19:57:46 +0300983 if ($value === $v)
984 {
985 return ' selected="selected"';
986 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000987 }
Andrey Andreeva587a932013-10-23 19:57:46 +0300988
989 return '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000990 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100991 elseif (($field === '' OR $value === '') OR ($field !== $value))
Derek Allard2067d1a2008-11-13 22:59:24 +0000992 {
Andrey Andreev901573c2012-01-11 01:40:48 +0200993 return '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000994 }
Barry Mienydd671972010-10-04 16:33:58 +0200995
Derek Allard2067d1a2008-11-13 22:59:24 +0000996 return ' selected="selected"';
997 }
Barry Mienydd671972010-10-04 16:33:58 +0200998
Derek Allard2067d1a2008-11-13 22:59:24 +0000999 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001000
Derek Allard2067d1a2008-11-13 22:59:24 +00001001 /**
1002 * Set Radio
1003 *
1004 * Enables radio buttons to be set to the value the user
1005 * selected in the event of an error
1006 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001007 * @param string
1008 * @param string
Timothy Warren0688ac92012-04-20 10:25:04 -04001009 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +00001010 * @return string
Barry Mienydd671972010-10-04 16:33:58 +02001011 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001012 public function set_radio($field = '', $value = '', $default = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001013 {
Andrey Andreev46ac8812012-02-28 14:32:54 +02001014 if ( ! isset($this->_field_data[$field], $this->_field_data[$field]['postdata']))
Derek Allard2067d1a2008-11-13 22:59:24 +00001015 {
Andrey Andreev6de924c2012-01-20 13:18:18 +02001016 return ($default === TRUE && count($this->_field_data) === 0) ? ' checked="checked"' : '';
Derek Allard2067d1a2008-11-13 22:59:24 +00001017 }
Barry Mienydd671972010-10-04 16:33:58 +02001018
Derek Allard2067d1a2008-11-13 22:59:24 +00001019 $field = $this->_field_data[$field]['postdata'];
Andrey Andreeva587a932013-10-23 19:57:46 +03001020 $value = (string) $value;
Derek Allard2067d1a2008-11-13 22:59:24 +00001021 if (is_array($field))
1022 {
Andrey Andreeva587a932013-10-23 19:57:46 +03001023 // Note: in_array('', array(0)) returns TRUE, do not use it
1024 foreach ($field as &$v)
Derek Allard2067d1a2008-11-13 22:59:24 +00001025 {
Andrey Andreeva587a932013-10-23 19:57:46 +03001026 if ($value === $v)
1027 {
1028 return ' checked="checked"';
1029 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001030 }
Andrey Andreeva587a932013-10-23 19:57:46 +03001031
1032 return '';
Derek Allard2067d1a2008-11-13 22:59:24 +00001033 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001034 elseif (($field === '' OR $value === '') OR ($field !== $value))
Derek Allard2067d1a2008-11-13 22:59:24 +00001035 {
Andrey Andreev901573c2012-01-11 01:40:48 +02001036 return '';
Derek Allard2067d1a2008-11-13 22:59:24 +00001037 }
Barry Mienydd671972010-10-04 16:33:58 +02001038
Derek Allard2067d1a2008-11-13 22:59:24 +00001039 return ' checked="checked"';
1040 }
Barry Mienydd671972010-10-04 16:33:58 +02001041
Derek Allard2067d1a2008-11-13 22:59:24 +00001042 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001043
Derek Allard2067d1a2008-11-13 22:59:24 +00001044 /**
1045 * Set Checkbox
1046 *
1047 * Enables checkboxes to be set to the value the user
1048 * selected in the event of an error
1049 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001050 * @param string
1051 * @param string
Timothy Warren0688ac92012-04-20 10:25:04 -04001052 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +00001053 * @return string
Barry Mienydd671972010-10-04 16:33:58 +02001054 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001055 public function set_checkbox($field = '', $value = '', $default = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001056 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +02001057 // Logic is exactly the same as for radio fields
1058 return $this->set_radio($field, $value, $default);
Derek Allard2067d1a2008-11-13 22:59:24 +00001059 }
Barry Mienydd671972010-10-04 16:33:58 +02001060
Derek Allard2067d1a2008-11-13 22:59:24 +00001061 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001062
Derek Allard2067d1a2008-11-13 22:59:24 +00001063 /**
1064 * Required
1065 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001066 * @param string
1067 * @return bool
1068 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001069 public function required($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001070 {
Andrey Andreev78f55772012-04-03 19:59:08 +03001071 return is_array($str) ? (bool) count($str) : (trim($str) !== '');
Derek Allard2067d1a2008-11-13 22:59:24 +00001072 }
Barry Mienydd671972010-10-04 16:33:58 +02001073
Derek Allard2067d1a2008-11-13 22:59:24 +00001074 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001075
Derek Allard2067d1a2008-11-13 22:59:24 +00001076 /**
Dan Horrigan2280e8e2010-12-15 10:16:38 -05001077 * Performs a Regular Expression match test.
1078 *
Dan Horrigan2280e8e2010-12-15 10:16:38 -05001079 * @param string
Andrey Andreev78f55772012-04-03 19:59:08 +03001080 * @param string regex
Dan Horrigan2280e8e2010-12-15 10:16:38 -05001081 * @return bool
1082 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001083 public function regex_match($str, $regex)
Dan Horrigan2280e8e2010-12-15 10:16:38 -05001084 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +02001085 return (bool) preg_match($regex, $str);
Dan Horrigan2280e8e2010-12-15 10:16:38 -05001086 }
1087
1088 // --------------------------------------------------------------------
1089
1090 /**
Derek Allard2067d1a2008-11-13 22:59:24 +00001091 * Match one field to another
1092 *
Andrey Andreeva779b2c2012-10-26 16:25:47 +03001093 * @param string $str string to compare against
1094 * @param string $field
Derek Allard2067d1a2008-11-13 22:59:24 +00001095 * @return bool
1096 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001097 public function matches($str, $field)
Derek Allard2067d1a2008-11-13 22:59:24 +00001098 {
Andrey Andreeva779b2c2012-10-26 16:25:47 +03001099 return isset($this->_field_data[$field], $this->_field_data[$field]['postdata'])
1100 ? ($str === $this->_field_data[$field]['postdata'])
1101 : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001102 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001103
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001104 // --------------------------------------------------------------------
1105
1106 /**
Raul Baldner Juniorf38564d2012-10-11 11:32:23 -03001107 * Differs from another field
1108 *
1109 * @param string
1110 * @param string field
1111 * @return bool
1112 */
1113 public function differs($str, $field)
1114 {
1115 return ! (isset($this->_field_data[$field]) && $this->_field_data[$field]['postdata'] === $str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001116 }
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001117
1118 // --------------------------------------------------------------------
1119
1120 /**
Andrey Andreevd09d6502012-01-03 06:38:33 +02001121 * Is Unique
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001122 *
Andrey Andreevd09d6502012-01-03 06:38:33 +02001123 * Check if the input value doesn't already exist
1124 * in the specified database field.
1125 *
Andrey Andreev9a0e0c72014-04-09 15:10:27 +03001126 * @param string $str
1127 * @param string $field
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001128 * @return bool
1129 */
1130 public function is_unique($str, $field)
1131 {
Andrey Andreev7a7ad782012-11-12 17:21:01 +02001132 sscanf($field, '%[^.].%[^.]', $table, $field);
Andrey Andreev9a0e0c72014-04-09 15:10:27 +03001133 return isset($this->CI->db)
1134 ? ($this->CI->db->limit(1)->get_where($table, array($field => $str))->num_rows() === 0)
1135 : FALSE;
Greg Aker03abee32011-12-25 00:31:29 -06001136 }
Barry Mienydd671972010-10-04 16:33:58 +02001137
Derek Allard2067d1a2008-11-13 22:59:24 +00001138 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001139
Derek Allard2067d1a2008-11-13 22:59:24 +00001140 /**
1141 * Minimum Length
1142 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001143 * @param string
Michiel Vugteveena8221ad2012-06-14 23:26:34 +02001144 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +00001145 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001146 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001147 public function min_length($str, $val)
Derek Allard2067d1a2008-11-13 22:59:24 +00001148 {
Michiel Vugteveenceaf8872012-06-15 11:56:24 +02001149 if ( ! is_numeric($val))
Derek Allard2067d1a2008-11-13 22:59:24 +00001150 {
1151 return FALSE;
1152 }
1153
Andrey Andreev78f55772012-04-03 19:59:08 +03001154 return (MB_ENABLED === TRUE)
1155 ? ($val <= mb_strlen($str))
Michiel Vugteveenceaf8872012-06-15 11:56:24 +02001156 : ($val <= strlen($str));
Derek Allard2067d1a2008-11-13 22:59:24 +00001157 }
Barry Mienydd671972010-10-04 16:33:58 +02001158
Derek Allard2067d1a2008-11-13 22:59:24 +00001159 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001160
Derek Allard2067d1a2008-11-13 22:59:24 +00001161 /**
1162 * Max Length
1163 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001164 * @param string
Michiel Vugteveena8221ad2012-06-14 23:26:34 +02001165 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +00001166 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001167 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001168 public function max_length($str, $val)
Derek Allard2067d1a2008-11-13 22:59:24 +00001169 {
Michiel Vugteveenceaf8872012-06-15 11:56:24 +02001170 if ( ! is_numeric($val))
Derek Allard2067d1a2008-11-13 22:59:24 +00001171 {
1172 return FALSE;
1173 }
1174
Andrey Andreev78f55772012-04-03 19:59:08 +03001175 return (MB_ENABLED === TRUE)
1176 ? ($val >= mb_strlen($str))
1177 : ($val >= strlen($str));
Derek Allard2067d1a2008-11-13 22:59:24 +00001178 }
Barry Mienydd671972010-10-04 16:33:58 +02001179
Derek Allard2067d1a2008-11-13 22:59:24 +00001180 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001181
Derek Allard2067d1a2008-11-13 22:59:24 +00001182 /**
1183 * Exact Length
1184 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001185 * @param string
Michiel Vugteveeneccde132012-06-14 23:22:26 +02001186 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +00001187 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001188 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001189 public function exact_length($str, $val)
Derek Allard2067d1a2008-11-13 22:59:24 +00001190 {
Michiel Vugteveenceaf8872012-06-15 11:56:24 +02001191 if ( ! is_numeric($val))
Derek Allard2067d1a2008-11-13 22:59:24 +00001192 {
1193 return FALSE;
1194 }
1195
Andrey Andreev78f55772012-04-03 19:59:08 +03001196 return (MB_ENABLED === TRUE)
Andrey Andreev9a0e0c72014-04-09 15:10:27 +03001197 ? (mb_strlen($str) === (int) $val)
1198 : (strlen($str) === (int) $val);
Derek Allard2067d1a2008-11-13 22:59:24 +00001199 }
Barry Mienydd671972010-10-04 16:33:58 +02001200
Derek Allard2067d1a2008-11-13 22:59:24 +00001201 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001202
Derek Allard2067d1a2008-11-13 22:59:24 +00001203 /**
Andrey Andreevdaaca882012-11-26 22:16:12 +02001204 * Valid URL
1205 *
1206 * @param string $str
1207 * @return bool
1208 */
1209 public function valid_url($str)
1210 {
1211 if (empty($str))
1212 {
1213 return FALSE;
1214 }
1215 elseif (preg_match('/^(?:([^:]*)\:)?\/\/(.+)$/', $str, $matches))
1216 {
1217 if (empty($matches[2]))
1218 {
1219 return FALSE;
1220 }
1221 elseif ( ! in_array($matches[1], array('http', 'https'), TRUE))
1222 {
1223 return FALSE;
1224 }
1225
1226 $str = $matches[2];
1227 }
1228
1229 $str = 'http://'.$str;
1230
1231 // There's a bug affecting PHP 5.2.13, 5.3.2 that considers the
1232 // underscore to be a valid hostname character instead of a dash.
1233 // Reference: https://bugs.php.net/bug.php?id=51192
Andrey Andreev9a0e0c72014-04-09 15:10:27 +03001234 if (version_compare(PHP_VERSION, '5.2.13', '==') OR version_compare(PHP_VERSION, '5.3.2', '=='))
Andrey Andreevdaaca882012-11-26 22:16:12 +02001235 {
1236 sscanf($str, 'http://%[^/]', $host);
1237 $str = substr_replace($str, strtr($host, array('_' => '-', '-' => '_')), 7, strlen($host));
1238 }
1239
1240 return (filter_var($str, FILTER_VALIDATE_URL) !== FALSE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001241 }
1242
1243 // --------------------------------------------------------------------
1244
1245 /**
1246 * Valid Email
1247 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001248 * @param string
1249 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001250 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001251 public function valid_email($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001252 {
Andrey Andreevf9201ae2014-06-01 12:57:30 +03001253 if (function_exists('idn_to_ascii') && $atpos = strpos($str, '@'))
Andrey Andreev95496662014-06-01 00:00:13 +03001254 {
Andrey Andreevf9201ae2014-06-01 12:57:30 +03001255 $str = substr($str, 0, ++$atpos).idn_to_ascii(substr($str, $atpos));
Andrey Andreev95496662014-06-01 00:00:13 +03001256 }
1257
Andrey Andreev580388b2012-06-27 15:43:46 +03001258 return (bool) filter_var($str, FILTER_VALIDATE_EMAIL);
Derek Allard2067d1a2008-11-13 22:59:24 +00001259 }
1260
1261 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001262
Derek Allard2067d1a2008-11-13 22:59:24 +00001263 /**
1264 * Valid Emails
1265 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001266 * @param string
1267 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001268 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001269 public function valid_emails($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001270 {
1271 if (strpos($str, ',') === FALSE)
1272 {
1273 return $this->valid_email(trim($str));
1274 }
Barry Mienydd671972010-10-04 16:33:58 +02001275
Pascal Kriete14287f32011-02-14 13:39:34 -05001276 foreach (explode(',', $str) as $email)
Derek Allard2067d1a2008-11-13 22:59:24 +00001277 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +02001278 if (trim($email) !== '' && $this->valid_email(trim($email)) === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001279 {
1280 return FALSE;
1281 }
1282 }
Barry Mienydd671972010-10-04 16:33:58 +02001283
Derek Allard2067d1a2008-11-13 22:59:24 +00001284 return TRUE;
1285 }
1286
1287 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001288
Derek Allard2067d1a2008-11-13 22:59:24 +00001289 /**
1290 * Validate IP Address
1291 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001292 * @param string
Andrey Andreev5a257182012-06-10 06:18:14 +03001293 * @param string 'ipv4' or 'ipv6' to validate a specific IP format
Bo-Yi Wu013c8952011-09-12 15:03:44 +08001294 * @return bool
Derek Allard2067d1a2008-11-13 22:59:24 +00001295 */
Andrey Andreev5a257182012-06-10 06:18:14 +03001296 public function valid_ip($ip, $which = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001297 {
Andrey Andreev5a257182012-06-10 06:18:14 +03001298 return $this->CI->input->valid_ip($ip, $which);
Derek Allard2067d1a2008-11-13 22:59:24 +00001299 }
1300
1301 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001302
Derek Allard2067d1a2008-11-13 22:59:24 +00001303 /**
1304 * Alpha
1305 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001306 * @param string
1307 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001308 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001309 public function alpha($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001310 {
Andrey Andreevacb962e2012-06-27 12:04:24 +03001311 return ctype_alpha($str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001312 }
Barry Mienydd671972010-10-04 16:33:58 +02001313
Derek Allard2067d1a2008-11-13 22:59:24 +00001314 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001315
Derek Allard2067d1a2008-11-13 22:59:24 +00001316 /**
1317 * Alpha-numeric
1318 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001319 * @param string
1320 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001321 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001322 public function alpha_numeric($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001323 {
Andrey Andreevacb962e2012-06-27 12:04:24 +03001324 return ctype_alnum((string) $str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001325 }
Barry Mienydd671972010-10-04 16:33:58 +02001326
Derek Allard2067d1a2008-11-13 22:59:24 +00001327 // --------------------------------------------------------------------
Sajan Parikh2d1608a2013-02-02 08:00:39 -06001328
1329 /**
1330 * Alpha-numeric w/ spaces
1331 *
1332 * @param string
1333 * @return bool
1334 */
1335 public function alpha_numeric_spaces($str)
1336 {
Sajan Parikhdf3bfed2013-02-04 12:25:49 -06001337 return (bool) preg_match('/^[A-Z0-9 ]+$/i', $str);
Sajan Parikh2d1608a2013-02-02 08:00:39 -06001338 }
1339
1340 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001341
Derek Allard2067d1a2008-11-13 22:59:24 +00001342 /**
1343 * Alpha-numeric with underscores and dashes
1344 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001345 * @param string
1346 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001347 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001348 public function alpha_dash($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001349 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +02001350 return (bool) preg_match('/^[a-z0-9_-]+$/i', $str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001351 }
Barry Mienydd671972010-10-04 16:33:58 +02001352
Derek Allard2067d1a2008-11-13 22:59:24 +00001353 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001354
Derek Allard2067d1a2008-11-13 22:59:24 +00001355 /**
1356 * Numeric
1357 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001358 * @param string
1359 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001360 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001361 public function numeric($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001362 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +02001363 return (bool) preg_match('/^[\-+]?[0-9]*\.?[0-9]+$/', $str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001364
1365 }
1366
1367 // --------------------------------------------------------------------
1368
Barry Mienydd671972010-10-04 16:33:58 +02001369 /**
Derek Allard2067d1a2008-11-13 22:59:24 +00001370 * Integer
1371 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001372 * @param string
1373 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001374 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001375 public function integer($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001376 {
Phil Sturgeonef112c02011-02-07 13:01:47 +00001377 return (bool) preg_match('/^[\-+]?[0-9]+$/', $str);
1378 }
1379
1380 // --------------------------------------------------------------------
1381
1382 /**
1383 * Decimal number
1384 *
Phil Sturgeonef112c02011-02-07 13:01:47 +00001385 * @param string
1386 * @return bool
1387 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001388 public function decimal($str)
Phil Sturgeonef112c02011-02-07 13:01:47 +00001389 {
1390 return (bool) preg_match('/^[\-+]?[0-9]+\.[0-9]+$/', $str);
1391 }
1392
1393 // --------------------------------------------------------------------
1394
1395 /**
Andrey Andreevc68905a2012-02-02 21:41:54 +02001396 * Greater than
Phil Sturgeonef112c02011-02-07 13:01:47 +00001397 *
Phil Sturgeonef112c02011-02-07 13:01:47 +00001398 * @param string
Timothy Warren0688ac92012-04-20 10:25:04 -04001399 * @param int
Phil Sturgeonef112c02011-02-07 13:01:47 +00001400 * @return bool
1401 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001402 public function greater_than($str, $min)
Phil Sturgeonef112c02011-02-07 13:01:47 +00001403 {
Andrey Andreev78f55772012-04-03 19:59:08 +03001404 return is_numeric($str) ? ($str > $min) : FALSE;
Phil Sturgeonef112c02011-02-07 13:01:47 +00001405 }
1406
1407 // --------------------------------------------------------------------
1408
1409 /**
Nick Busey98c347d2012-02-02 11:07:03 -07001410 * Equal to or Greater than
1411 *
Nick Busey98c347d2012-02-02 11:07:03 -07001412 * @param string
Timothy Warren0688ac92012-04-20 10:25:04 -04001413 * @param int
Nick Busey98c347d2012-02-02 11:07:03 -07001414 * @return bool
1415 */
Andrey Andreev3b2c5082012-03-07 22:49:24 +02001416 public function greater_than_equal_to($str, $min)
Nick Busey98c347d2012-02-02 11:07:03 -07001417 {
Andrey Andreev78f55772012-04-03 19:59:08 +03001418 return is_numeric($str) ? ($str >= $min) : FALSE;
Phil Sturgeonef112c02011-02-07 13:01:47 +00001419 }
1420
1421 // --------------------------------------------------------------------
1422
1423 /**
1424 * Less than
1425 *
Phil Sturgeonef112c02011-02-07 13:01:47 +00001426 * @param string
Timothy Warren0688ac92012-04-20 10:25:04 -04001427 * @param int
Phil Sturgeonef112c02011-02-07 13:01:47 +00001428 * @return bool
1429 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001430 public function less_than($str, $max)
Phil Sturgeonef112c02011-02-07 13:01:47 +00001431 {
Andrey Andreev78f55772012-04-03 19:59:08 +03001432 return is_numeric($str) ? ($str < $max) : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001433 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001434
1435 // --------------------------------------------------------------------
1436
Barry Mienydd671972010-10-04 16:33:58 +02001437 /**
Nick Busey98c347d2012-02-02 11:07:03 -07001438 * Equal to or Less than
1439 *
Nick Busey98c347d2012-02-02 11:07:03 -07001440 * @param string
Timothy Warren0688ac92012-04-20 10:25:04 -04001441 * @param int
Nick Busey98c347d2012-02-02 11:07:03 -07001442 * @return bool
1443 */
Andrey Andreev3b2c5082012-03-07 22:49:24 +02001444 public function less_than_equal_to($str, $max)
Nick Busey98c347d2012-02-02 11:07:03 -07001445 {
Andrey Andreev78f55772012-04-03 19:59:08 +03001446 return is_numeric($str) ? ($str <= $max) : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001447 }
1448
1449 // --------------------------------------------------------------------
1450
Barry Mienydd671972010-10-04 16:33:58 +02001451 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -05001452 * Is a Natural number (0,1,2,3, etc.)
Barry Mienydd671972010-10-04 16:33:58 +02001453 *
Barry Mienydd671972010-10-04 16:33:58 +02001454 * @param string
1455 * @return bool
1456 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001457 public function is_natural($str)
Barry Mienydd671972010-10-04 16:33:58 +02001458 {
Andrey Andreevacb962e2012-06-27 12:04:24 +03001459 return ctype_digit((string) $str);
Barry Mienydd671972010-10-04 16:33:58 +02001460 }
1461
1462 // --------------------------------------------------------------------
1463
1464 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -05001465 * Is a Natural number, but not a zero (1,2,3, etc.)
Barry Mienydd671972010-10-04 16:33:58 +02001466 *
Barry Mienydd671972010-10-04 16:33:58 +02001467 * @param string
1468 * @return bool
1469 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001470 public function is_natural_no_zero($str)
Barry Mienydd671972010-10-04 16:33:58 +02001471 {
Andrey Andreevacb962e2012-06-27 12:04:24 +03001472 return ($str != 0 && ctype_digit((string) $str));
Barry Mienydd671972010-10-04 16:33:58 +02001473 }
1474
Derek Allard2067d1a2008-11-13 22:59:24 +00001475 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001476
Derek Allard2067d1a2008-11-13 22:59:24 +00001477 /**
1478 * Valid Base64
1479 *
1480 * Tests a string for characters outside of the Base64 alphabet
1481 * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045
1482 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001483 * @param string
1484 * @return bool
1485 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001486 public function valid_base64($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001487 {
Andrey Andreevcd9797a2013-06-28 14:03:48 +03001488 return (base64_encode(base64_decode($str)) === $str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001489 }
Barry Mienydd671972010-10-04 16:33:58 +02001490
Derek Allard2067d1a2008-11-13 22:59:24 +00001491 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001492
Derek Allard2067d1a2008-11-13 22:59:24 +00001493 /**
1494 * Prep data for form
1495 *
1496 * This function allows HTML to be safely shown in a form.
1497 * Special characters are converted.
1498 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001499 * @param string
1500 * @return string
1501 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001502 public function prep_for_form($data = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001503 {
Andrey Andreev7c4d1062012-11-01 15:14:34 +02001504 if ($this->_safe_form_data === FALSE OR empty($data))
1505 {
1506 return $data;
1507 }
1508
Derek Allard2067d1a2008-11-13 22:59:24 +00001509 if (is_array($data))
1510 {
1511 foreach ($data as $key => $val)
1512 {
1513 $data[$key] = $this->prep_for_form($val);
1514 }
Barry Mienydd671972010-10-04 16:33:58 +02001515
Derek Allard2067d1a2008-11-13 22:59:24 +00001516 return $data;
1517 }
Barry Mienydd671972010-10-04 16:33:58 +02001518
Andrey Andreev901573c2012-01-11 01:40:48 +02001519 return str_replace(array("'", '"', '<', '>'), array('&#39;', '&quot;', '&lt;', '&gt;'), stripslashes($data));
Derek Allard2067d1a2008-11-13 22:59:24 +00001520 }
Barry Mienydd671972010-10-04 16:33:58 +02001521
Derek Allard2067d1a2008-11-13 22:59:24 +00001522 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001523
Derek Allard2067d1a2008-11-13 22:59:24 +00001524 /**
1525 * Prep URL
1526 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001527 * @param string
1528 * @return string
Barry Mienydd671972010-10-04 16:33:58 +02001529 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001530 public function prep_url($str = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001531 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001532 if ($str === 'http://' OR $str === '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001533 {
1534 return '';
1535 }
Barry Mienydd671972010-10-04 16:33:58 +02001536
Andrey Andreev901573c2012-01-11 01:40:48 +02001537 if (strpos($str, 'http://') !== 0 && strpos($str, 'https://') !== 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001538 {
Andrey Andreev901573c2012-01-11 01:40:48 +02001539 return 'http://'.$str;
Derek Allard2067d1a2008-11-13 22:59:24 +00001540 }
Barry Mienydd671972010-10-04 16:33:58 +02001541
Derek Allard2067d1a2008-11-13 22:59:24 +00001542 return $str;
1543 }
Barry Mienydd671972010-10-04 16:33:58 +02001544
Derek Allard2067d1a2008-11-13 22:59:24 +00001545 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001546
Derek Allard2067d1a2008-11-13 22:59:24 +00001547 /**
1548 * Strip Image Tags
1549 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001550 * @param string
1551 * @return string
Barry Mienydd671972010-10-04 16:33:58 +02001552 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001553 public function strip_image_tags($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001554 {
Andrey Andreev1a24a9d2012-06-27 00:52:47 +03001555 return $this->CI->security->strip_image_tags($str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001556 }
Barry Mienydd671972010-10-04 16:33:58 +02001557
Derek Allard2067d1a2008-11-13 22:59:24 +00001558 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001559
Derek Allard2067d1a2008-11-13 22:59:24 +00001560 /**
Derek Allard2067d1a2008-11-13 22:59:24 +00001561 * Convert PHP tags to entities
1562 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001563 * @param string
1564 * @return string
Barry Mienydd671972010-10-04 16:33:58 +02001565 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001566 public function encode_php_tags($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001567 {
Andrey Andreev838a9d62012-12-03 14:37:47 +02001568 return str_replace(array('<?', '?>'), array('&lt;?', '?&gt;'), $str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001569 }
1570
JonoB099c4782012-03-04 14:37:30 +00001571 // --------------------------------------------------------------------
Andrey Andreevc8da4fe2012-03-04 19:20:33 +02001572
1573 /**
1574 * Reset validation vars
1575 *
1576 * Prevents subsequent validation routines from being affected by the
JonoB099c4782012-03-04 14:37:30 +00001577 * results of any previous validation routine due to the CI singleton.
Andrey Andreevc8da4fe2012-03-04 19:20:33 +02001578 *
Andrey Andreeva89c1da2014-02-08 19:03:35 +02001579 * @return CI_Form_validation
Andrey Andreevc8da4fe2012-03-04 19:20:33 +02001580 */
JonoB883f80f2012-03-05 09:51:27 +00001581 public function reset_validation()
Andrey Andreevc8da4fe2012-03-04 19:20:33 +02001582 {
JonoB099c4782012-03-04 14:37:30 +00001583 $this->_field_data = array();
1584 $this->_config_rules = array();
1585 $this->_error_array = array();
1586 $this->_error_messages = array();
1587 $this->error_string = '';
Andrey Andreeva89c1da2014-02-08 19:03:35 +02001588 return $this;
Andrey Andreevc8da4fe2012-03-04 19:20:33 +02001589 }
1590
Derek Allard2067d1a2008-11-13 22:59:24 +00001591}
Derek Allard2067d1a2008-11-13 22:59:24 +00001592
1593/* End of file Form_validation.php */
Eric Roberts24a13f52012-12-12 07:09:42 -06001594/* Location: ./system/libraries/Form_validation.php */