blob: f3c8826171c08f1e7727164aa21905d3f42a1d38 [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Eric Barnescccde962011-12-04 00:01:17 -05008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Eric Barnescccde962011-12-04 00:01:17 -050010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
darwinel871754a2014-02-11 17:34:57 +010021 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000028
Derek Allard2067d1a2008-11-13 22:59:24 +000029/**
30 * Form Validation Class
31 *
32 * @package CodeIgniter
33 * @subpackage Libraries
34 * @category Validation
Derek Jonesf4a4bd82011-10-20 12:18:42 -050035 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000036 * @link http://codeigniter.com/user_guide/libraries/form_validation.html
37 */
38class CI_Form_validation {
Barry Mienydd671972010-10-04 16:33:58 +020039
Timothy Warren0688ac92012-04-20 10:25:04 -040040 /**
41 * Reference to the CodeIgniter instance
42 *
43 * @var object
44 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +010045 protected $CI;
Derek Allard2067d1a2008-11-13 22:59:24 +000046
Timothy Warren0688ac92012-04-20 10:25:04 -040047 /**
48 * Validation data for the current form submission
49 *
50 * @var array
51 */
Andrey Andreev56454792012-05-17 14:32:19 +030052 protected $_field_data = array();
53
Timothy Warren0688ac92012-04-20 10:25:04 -040054 /**
55 * Validation rules for the current form
56 *
57 * @var array
58 */
Andrey Andreev56454792012-05-17 14:32:19 +030059 protected $_config_rules = array();
60
Timothy Warren0688ac92012-04-20 10:25:04 -040061 /**
62 * Array of validation errors
63 *
64 * @var array
65 */
Andrey Andreev78f55772012-04-03 19:59:08 +030066 protected $_error_array = array();
Andrey Andreev56454792012-05-17 14:32:19 +030067
Timothy Warren0688ac92012-04-20 10:25:04 -040068 /**
69 * Array of custom error messages
70 *
71 * @var array
72 */
Andrey Andreev78f55772012-04-03 19:59:08 +030073 protected $_error_messages = array();
Andrey Andreev56454792012-05-17 14:32:19 +030074
Timothy Warren0688ac92012-04-20 10:25:04 -040075 /**
76 * Start tag for error wrapping
77 *
78 * @var string
79 */
Andrey Andreev78f55772012-04-03 19:59:08 +030080 protected $_error_prefix = '<p>';
Andrey Andreev56454792012-05-17 14:32:19 +030081
Timothy Warren0688ac92012-04-20 10:25:04 -040082 /**
83 * End tag for error wrapping
Andrey Andreev56454792012-05-17 14:32:19 +030084 *
Timothy Warren0688ac92012-04-20 10:25:04 -040085 * @var string
86 */
Andrey Andreev78f55772012-04-03 19:59:08 +030087 protected $_error_suffix = '</p>';
Andrey Andreev56454792012-05-17 14:32:19 +030088
Timothy Warren0688ac92012-04-20 10:25:04 -040089 /**
90 * Custom error message
91 *
92 * @var string
93 */
Andrey Andreev78f55772012-04-03 19:59:08 +030094 protected $error_string = '';
Andrey Andreev56454792012-05-17 14:32:19 +030095
Timothy Warren0688ac92012-04-20 10:25:04 -040096 /**
97 * Whether the form data has been validated as safe
98 *
99 * @var bool
100 */
Andrey Andreev78f55772012-04-03 19:59:08 +0300101 protected $_safe_form_data = FALSE;
Andrey Andreev56454792012-05-17 14:32:19 +0300102
Timothy Warren0688ac92012-04-20 10:25:04 -0400103 /**
104 * Custom data to validate
105 *
106 * @var array
107 */
Andrey Andreevcff35802012-11-26 15:49:52 +0200108 public $validation_data = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000109
Timothy Warren0688ac92012-04-20 10:25:04 -0400110 /**
111 * Initialize Form_Validation class
112 *
Andrey Andreev56454792012-05-17 14:32:19 +0300113 * @param array $rules
114 * @return void
Timothy Warren0688ac92012-04-20 10:25:04 -0400115 */
Greg Akera9263282010-11-10 15:26:43 -0600116 public function __construct($rules = array())
Barry Mienydd671972010-10-04 16:33:58 +0200117 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000118 $this->CI =& get_instance();
Barry Mienydd671972010-10-04 16:33:58 +0200119
Mike Funk326a5e72012-02-24 10:06:28 -0500120 // applies delimiters set in config file.
Mike Funk7f42d062012-03-08 09:00:57 -0500121 if (isset($rules['error_prefix']))
122 {
123 $this->_error_prefix = $rules['error_prefix'];
124 unset($rules['error_prefix']);
125 }
126 if (isset($rules['error_suffix']))
127 {
128 $this->_error_suffix = $rules['error_suffix'];
129 unset($rules['error_suffix']);
130 }
Andrey Andreev31cf46e2012-03-20 15:48:00 +0200131
Derek Allard2067d1a2008-11-13 22:59:24 +0000132 // Validation rules can be stored in a config file.
133 $this->_config_rules = $rules;
Barry Mienydd671972010-10-04 16:33:58 +0200134
Derek Allard2067d1a2008-11-13 22:59:24 +0000135 // Automatically load the form helper
136 $this->CI->load->helper('form');
137
Andrey Andreev901573c2012-01-11 01:40:48 +0200138 log_message('debug', 'Form Validation Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000139 }
Barry Mienydd671972010-10-04 16:33:58 +0200140
Derek Allard2067d1a2008-11-13 22:59:24 +0000141 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200142
Derek Allard2067d1a2008-11-13 22:59:24 +0000143 /**
144 * Set Rules
145 *
146 * This function takes an array of field names and validation
Andrey Andreev4b90a372014-03-10 10:24:24 +0200147 * rules as input, any custom error messages, validates the info,
Ahmedul Haque Abid42b40002014-01-09 01:10:25 +0600148 * and stores it
Derek Allard2067d1a2008-11-13 22:59:24 +0000149 *
Timothy Warren0688ac92012-04-20 10:25:04 -0400150 * @param mixed $field
151 * @param string $label
152 * @param mixed $rules
Ahmedul Haque Abid0742fad2014-01-09 07:51:10 +0600153 * @param array $errors
Andrew Podner4296a652012-12-17 07:51:15 -0500154 * @return CI_Form_validation
Derek Allard2067d1a2008-11-13 22:59:24 +0000155 */
Andrey Andreev4b90a372014-03-10 10:24:24 +0200156 public function set_rules($field, $label = '', $rules = array(), $errors = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000157 {
158 // No reason to set rules if we have no POST data
JonoB099c4782012-03-04 14:37:30 +0000159 // or a validation array has not been specified
Andrey Andreev3b2c5082012-03-07 22:49:24 +0200160 if ($this->CI->input->method() !== 'post' && empty($this->validation_data))
Derek Allard2067d1a2008-11-13 22:59:24 +0000161 {
Greg Aker9f9af602010-11-10 15:41:51 -0600162 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000163 }
Barry Mienydd671972010-10-04 16:33:58 +0200164
tiyowanc2acb232012-03-14 21:24:00 +0400165 // If an array was passed via the first parameter instead of individual string
Derek Allard2067d1a2008-11-13 22:59:24 +0000166 // values we cycle through it and recursively call this function.
167 if (is_array($field))
168 {
169 foreach ($field as $row)
170 {
171 // Houston, we have a problem...
Andrey Andreev78f55772012-04-03 19:59:08 +0300172 if ( ! isset($row['field'], $row['rules']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000173 {
174 continue;
175 }
176
177 // If the field label wasn't passed we use the field name
Andrey Andreev78f55772012-04-03 19:59:08 +0300178 $label = isset($row['label']) ? $row['label'] : $row['field'];
Derek Allard2067d1a2008-11-13 22:59:24 +0000179
Ahmedul Haque Abid42b40002014-01-09 01:10:25 +0600180 // Add the custom error message array
Ahmedul Haque Abidea294882014-01-09 16:01:31 +0600181 $errors = (isset($row['errors']) && is_array($row['errors'])) ? $row['errors'] : array();
Ahmedul Haque Abid42b40002014-01-09 01:10:25 +0600182
Derek Allard2067d1a2008-11-13 22:59:24 +0000183 // Here we go!
Ahmedul Haque Abidbc1cbad2014-01-09 07:53:34 +0600184 $this->set_rules($row['field'], $label, $row['rules'], $errors);
Derek Allard2067d1a2008-11-13 22:59:24 +0000185 }
Andrey Andreev78f55772012-04-03 19:59:08 +0300186
Greg Aker9f9af602010-11-10 15:41:51 -0600187 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000188 }
Barry Mienydd671972010-10-04 16:33:58 +0200189
Derek Allard2067d1a2008-11-13 22:59:24 +0000190 // No fields? Nothing to do...
Andrey Andreev4b90a372014-03-10 10:24:24 +0200191 if ( ! is_string($field) OR $field === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000192 {
Greg Aker9f9af602010-11-10 15:41:51 -0600193 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000194 }
Andrey Andreev4b90a372014-03-10 10:24:24 +0200195 elseif ( ! is_array($rules))
196 {
197 // BC: Convert pipe-separated rules string to an array
198 if (is_string($rules))
199 {
200 $rules = explode('|', $rules);
201 }
202 else
203 {
204 return $this;
205 }
206 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000207
208 // If the field label wasn't passed we use the field name
Alex Bilbied261b1e2012-06-02 11:12:16 +0100209 $label = ($label === '') ? $field : $label;
Derek Allard2067d1a2008-11-13 22:59:24 +0000210
Andrey Andreevfde170c2014-03-10 19:55:11 +0200211 $indexes = array();
212
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200213 // Is the field name an array? If it is an array, we break it apart
Barry Mienydd671972010-10-04 16:33:58 +0200214 // into its components so that we can fetch the corresponding POST data later
Andrey Andreev4b90a372014-03-10 10:24:24 +0200215 if (($is_array = (bool) preg_match_all('/\[(.*?)\]/', $field, $matches)) === TRUE)
Barry Mienydd671972010-10-04 16:33:58 +0200216 {
Andrey Andreev7a7ad782012-11-12 17:21:01 +0200217 sscanf($field, '%[^[][', $indexes[0]);
Derek Allard2067d1a2008-11-13 22:59:24 +0000218
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200219 for ($i = 0, $c = count($matches[0]); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000220 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100221 if ($matches[1][$i] !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000222 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200223 $indexes[] = $matches[1][$i];
Derek Allard2067d1a2008-11-13 22:59:24 +0000224 }
225 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000226 }
Barry Mienydd671972010-10-04 16:33:58 +0200227
228 // Build our master array
Derek Allard2067d1a2008-11-13 22:59:24 +0000229 $this->_field_data[$field] = array(
Andrey Andreev56454792012-05-17 14:32:19 +0300230 'field' => $field,
231 'label' => $label,
232 'rules' => $rules,
Ahmedul Haque Abid7945d302014-01-09 16:50:23 +0600233 'errors' => $errors,
Andrey Andreev56454792012-05-17 14:32:19 +0300234 'is_array' => $is_array,
235 'keys' => $indexes,
236 'postdata' => NULL,
237 'error' => ''
Phil Sturgeonef112c02011-02-07 13:01:47 +0000238 );
Greg Aker9f9af602010-11-10 15:41:51 -0600239
240 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000241 }
242
243 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200244
Derek Allard2067d1a2008-11-13 22:59:24 +0000245 /**
JonoB099c4782012-03-04 14:37:30 +0000246 * By default, form validation uses the $_POST array to validate
Andrey Andreevc8da4fe2012-03-04 19:20:33 +0200247 *
JonoB099c4782012-03-04 14:37:30 +0000248 * If an array is set through this method, then this array will
249 * be used instead of the $_POST array
Andrey Andreev3b2c5082012-03-07 22:49:24 +0200250 *
251 * Note that if you are validating multiple arrays, then the
252 * reset_validation() function should be called after validating
JonoB883f80f2012-03-05 09:51:27 +0000253 * each array due to the limitations of CI's singleton
Andrey Andreevc8da4fe2012-03-04 19:20:33 +0200254 *
255 * @param array $data
Andrey Andreeva89c1da2014-02-08 19:03:35 +0200256 * @return CI_Form_validation
JonoB099c4782012-03-04 14:37:30 +0000257 */
Andrey Andreeva4712f52014-01-06 11:25:46 +0200258 public function set_data(array $data)
JonoB099c4782012-03-04 14:37:30 +0000259 {
Andrey Andreeva4712f52014-01-06 11:25:46 +0200260 if ( ! empty($data))
JonoB099c4782012-03-04 14:37:30 +0000261 {
Andrey Andreevc8da4fe2012-03-04 19:20:33 +0200262 $this->validation_data = $data;
JonoB099c4782012-03-04 14:37:30 +0000263 }
Andrey Andreeva89c1da2014-02-08 19:03:35 +0200264
265 return $this;
JonoB099c4782012-03-04 14:37:30 +0000266 }
Andrey Andreevc8da4fe2012-03-04 19:20:33 +0200267
JonoB099c4782012-03-04 14:37:30 +0000268 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000269
270 /**
271 * Set Error Message
272 *
Andrey Andreev78f55772012-04-03 19:59:08 +0300273 * Lets users set their own error messages on the fly. Note:
274 * The key name has to match the function name that it corresponds to.
Derek Allard2067d1a2008-11-13 22:59:24 +0000275 *
Andrey Andreev78f55772012-04-03 19:59:08 +0300276 * @param array
Derek Allard2067d1a2008-11-13 22:59:24 +0000277 * @param string
Andrew Podner4296a652012-12-17 07:51:15 -0500278 * @return CI_Form_validation
Derek Allard2067d1a2008-11-13 22:59:24 +0000279 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100280 public function set_message($lang, $val = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000281 {
282 if ( ! is_array($lang))
283 {
284 $lang = array($lang => $val);
285 }
Barry Mienydd671972010-10-04 16:33:58 +0200286
Derek Allard2067d1a2008-11-13 22:59:24 +0000287 $this->_error_messages = array_merge($this->_error_messages, $lang);
Greg Aker9f9af602010-11-10 15:41:51 -0600288 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000289 }
Barry Mienydd671972010-10-04 16:33:58 +0200290
Derek Allard2067d1a2008-11-13 22:59:24 +0000291 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200292
Derek Allard2067d1a2008-11-13 22:59:24 +0000293 /**
294 * Set The Error Delimiter
295 *
296 * Permits a prefix/suffix to be added to each error message
297 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000298 * @param string
299 * @param string
Andrew Podner4296a652012-12-17 07:51:15 -0500300 * @return CI_Form_validation
Barry Mienydd671972010-10-04 16:33:58 +0200301 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100302 public function set_error_delimiters($prefix = '<p>', $suffix = '</p>')
Derek Allard2067d1a2008-11-13 22:59:24 +0000303 {
304 $this->_error_prefix = $prefix;
305 $this->_error_suffix = $suffix;
Greg Aker9f9af602010-11-10 15:41:51 -0600306 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000307 }
308
309 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200310
Derek Allard2067d1a2008-11-13 22:59:24 +0000311 /**
312 * Get Error Message
313 *
314 * Gets the error message associated with a particular field
315 *
Andrey Andreeva4712f52014-01-06 11:25:46 +0200316 * @param string $field Field name
317 * @param string $prefix HTML start tag
Andrey Andreev868301a2014-01-06 12:29:50 +0200318 * @param string $suffix HTML end tag
Andrey Andreev78f55772012-04-03 19:59:08 +0300319 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200320 */
Andrey Andreeva4712f52014-01-06 11:25:46 +0200321 public function error($field, $prefix = '', $suffix = '')
Barry Mienydd671972010-10-04 16:33:58 +0200322 {
Andrey Andreev78f55772012-04-03 19:59:08 +0300323 if (empty($this->_field_data[$field]['error']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000324 {
325 return '';
326 }
Barry Mienydd671972010-10-04 16:33:58 +0200327
Alex Bilbied261b1e2012-06-02 11:12:16 +0100328 if ($prefix === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000329 {
330 $prefix = $this->_error_prefix;
331 }
332
Alex Bilbied261b1e2012-06-02 11:12:16 +0100333 if ($suffix === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000334 {
335 $suffix = $this->_error_suffix;
336 }
337
338 return $prefix.$this->_field_data[$field]['error'].$suffix;
339 }
340
341 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200342
Derek Allard2067d1a2008-11-13 22:59:24 +0000343 /**
Michiel Vugteveen676a0dd2012-03-02 10:10:34 +0100344 * Get Array of Error Messages
345 *
346 * Returns the error messages as an array
347 *
348 * @return array
349 */
350 public function error_array()
351 {
352 return $this->_error_array;
353 }
354
355 // --------------------------------------------------------------------
356
357 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000358 * Error String
359 *
360 * Returns the error messages as a string, wrapped in the error delimiters
361 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000362 * @param string
363 * @param string
Andrey Andreev78f55772012-04-03 19:59:08 +0300364 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200365 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100366 public function error_string($prefix = '', $suffix = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000367 {
vlakoff35672462013-02-15 01:36:04 +0100368 // No errors, validation passes!
Derek Allard2067d1a2008-11-13 22:59:24 +0000369 if (count($this->_error_array) === 0)
370 {
371 return '';
372 }
Barry Mienydd671972010-10-04 16:33:58 +0200373
Alex Bilbied261b1e2012-06-02 11:12:16 +0100374 if ($prefix === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000375 {
376 $prefix = $this->_error_prefix;
377 }
378
Alex Bilbied261b1e2012-06-02 11:12:16 +0100379 if ($suffix === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000380 {
381 $suffix = $this->_error_suffix;
382 }
Barry Mienydd671972010-10-04 16:33:58 +0200383
Derek Allard2067d1a2008-11-13 22:59:24 +0000384 // Generate the error string
385 $str = '';
386 foreach ($this->_error_array as $val)
387 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100388 if ($val !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000389 {
390 $str .= $prefix.$val.$suffix."\n";
391 }
392 }
Barry Mienydd671972010-10-04 16:33:58 +0200393
Derek Allard2067d1a2008-11-13 22:59:24 +0000394 return $str;
395 }
396
397 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200398
Derek Allard2067d1a2008-11-13 22:59:24 +0000399 /**
400 * Run the Validator
401 *
402 * This function does all the work.
403 *
Timothy Warren0688ac92012-04-20 10:25:04 -0400404 * @param string $group
Derek Allard2067d1a2008-11-13 22:59:24 +0000405 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +0200406 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100407 public function run($group = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000408 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500409 // Do we even have any data to process? Mm?
Andrey Andreev78f55772012-04-03 19:59:08 +0300410 $validation_array = empty($this->validation_data) ? $_POST : $this->validation_data;
JonoB099c4782012-03-04 14:37:30 +0000411 if (count($validation_array) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000412 {
413 return FALSE;
414 }
Barry Mienydd671972010-10-04 16:33:58 +0200415
Derek Allard2067d1a2008-11-13 22:59:24 +0000416 // Does the _field_data array containing the validation rules exist?
417 // If not, we look to see if they were assigned via a config file
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200418 if (count($this->_field_data) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000419 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500420 // No validation rules? We're done...
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200421 if (count($this->_config_rules) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000422 {
423 return FALSE;
424 }
Barry Mienydd671972010-10-04 16:33:58 +0200425
Andrey Andreev3b2803e2014-01-07 14:46:38 +0200426 if (empty($group))
427 {
428 // Is there a validation rule for the particular URI being accessed?
429 $group = trim($this->CI->uri->ruri_string(), '/');
430 isset($this->_config_rules[$group]) OR $group = $this->CI->router->class.'/'.$this->CI->router->method;
431 }
Barry Mienydd671972010-10-04 16:33:58 +0200432
Andrey Andreev3b2803e2014-01-07 14:46:38 +0200433 $this->set_rules(isset($this->_config_rules[$group]) ? $this->_config_rules[$group] : $this->_config_rules);
Barry Mienydd671972010-10-04 16:33:58 +0200434
Andrey Andreev901573c2012-01-11 01:40:48 +0200435 // Were we able to set the rules correctly?
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200436 if (count($this->_field_data) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000437 {
Andrey Andreev901573c2012-01-11 01:40:48 +0200438 log_message('debug', 'Unable to find validation rules');
Derek Allard2067d1a2008-11-13 22:59:24 +0000439 return FALSE;
440 }
441 }
Barry Mienydd671972010-10-04 16:33:58 +0200442
Derek Allard2067d1a2008-11-13 22:59:24 +0000443 // Load the language file containing error messages
444 $this->CI->lang->load('form_validation');
Barry Mienydd671972010-10-04 16:33:58 +0200445
Andrey Andreev751f2472012-11-03 18:26:27 +0200446 // Cycle through the rules for each field and match the corresponding $validation_data item
Derek Allard2067d1a2008-11-13 22:59:24 +0000447 foreach ($this->_field_data as $field => $row)
Barry Mienydd671972010-10-04 16:33:58 +0200448 {
Andrey Andreev751f2472012-11-03 18:26:27 +0200449 // Fetch the data from the validation_data array item and cache it in the _field_data array.
Derek Allard2067d1a2008-11-13 22:59:24 +0000450 // 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 +0200451 if ($row['is_array'] === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000452 {
JonoB099c4782012-03-04 14:37:30 +0000453 $this->_field_data[$field]['postdata'] = $this->_reduce_array($validation_array, $row['keys']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000454 }
Andrey Andreevfff6c2a2012-05-13 22:15:23 +0300455 elseif (isset($validation_array[$field]) && $validation_array[$field] !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000456 {
Andrey Andreev78f55772012-04-03 19:59:08 +0300457 $this->_field_data[$field]['postdata'] = $validation_array[$field];
Derek Allard2067d1a2008-11-13 22:59:24 +0000458 }
Andrey Andreev751f2472012-11-03 18:26:27 +0200459 }
Barry Mienydd671972010-10-04 16:33:58 +0200460
Andrey Andreev751f2472012-11-03 18:26:27 +0200461 // Execute validation rules
462 // Note: A second foreach (for now) is required in order to avoid false-positives
463 // for rules like 'matches', which correlate to other validation fields.
464 foreach ($this->_field_data as $field => $row)
465 {
Andrey Andreev3d9cec92012-07-08 21:50:19 +0300466 // Don't try to validate if we have no rules set
467 if (empty($row['rules']))
468 {
469 continue;
470 }
Barry Mienydd671972010-10-04 16:33:58 +0200471
Andrey Andreev4b90a372014-03-10 10:24:24 +0200472 $this->_execute($row, $row['rules'], $this->_field_data[$field]['postdata']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000473 }
474
475 // Did we end up with any errors?
476 $total_errors = count($this->_error_array);
Derek Allard2067d1a2008-11-13 22:59:24 +0000477 if ($total_errors > 0)
478 {
479 $this->_safe_form_data = TRUE;
480 }
481
482 // Now we need to re-set the POST data with the new, processed data
483 $this->_reset_post_array();
Barry Mienydd671972010-10-04 16:33:58 +0200484
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200485 return ($total_errors === 0);
Derek Allard2067d1a2008-11-13 22:59:24 +0000486 }
487
488 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200489
Derek Allard2067d1a2008-11-13 22:59:24 +0000490 /**
491 * Traverse a multidimensional $_POST array index until the data is found
492 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000493 * @param array
494 * @param array
Andrey Andreev78f55772012-04-03 19:59:08 +0300495 * @param int
Derek Allard2067d1a2008-11-13 22:59:24 +0000496 * @return mixed
Barry Mienydd671972010-10-04 16:33:58 +0200497 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100498 protected function _reduce_array($array, $keys, $i = 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000499 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200500 if (is_array($array) && isset($keys[$i]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000501 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200502 return isset($array[$keys[$i]]) ? $this->_reduce_array($array[$keys[$i]], $keys, ($i+1)) : NULL;
Derek Allard2067d1a2008-11-13 22:59:24 +0000503 }
Barry Mienydd671972010-10-04 16:33:58 +0200504
Andrey Andreev2d48b4f2012-11-23 17:33:21 +0200505 // NULL must be returned for empty fields
Andrey Andreev44c34632012-11-23 18:46:34 +0200506 return ($array === '') ? NULL : $array;
Derek Allard2067d1a2008-11-13 22:59:24 +0000507 }
508
509 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200510
Derek Allard2067d1a2008-11-13 22:59:24 +0000511 /**
512 * Re-populate the _POST array with our finalized and processed data
513 *
Andrey Andreev6de924c2012-01-20 13:18:18 +0200514 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200515 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100516 protected function _reset_post_array()
Derek Allard2067d1a2008-11-13 22:59:24 +0000517 {
518 foreach ($this->_field_data as $field => $row)
519 {
vlakoff1228fe22013-01-14 01:30:09 +0100520 if ($row['postdata'] !== NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000521 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200522 if ($row['is_array'] === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000523 {
524 if (isset($_POST[$row['field']]))
525 {
Andrey Andreevc2268712013-02-08 22:10:23 +0200526 $_POST[$row['field']] = $row['postdata'];
Derek Allard2067d1a2008-11-13 22:59:24 +0000527 }
528 }
529 else
530 {
Derek Jones63eeae32009-02-10 19:08:56 +0000531 // start with a reference
532 $post_ref =& $_POST;
Barry Mienydd671972010-10-04 16:33:58 +0200533
Derek Jones63eeae32009-02-10 19:08:56 +0000534 // before we assign values, make a reference to the right POST key
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200535 if (count($row['keys']) === 1)
Derek Allard2067d1a2008-11-13 22:59:24 +0000536 {
Derek Jones63eeae32009-02-10 19:08:56 +0000537 $post_ref =& $post_ref[current($row['keys'])];
Derek Allard2067d1a2008-11-13 22:59:24 +0000538 }
539 else
540 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000541 foreach ($row['keys'] as $val)
542 {
Derek Jones63eeae32009-02-10 19:08:56 +0000543 $post_ref =& $post_ref[$val];
Derek Allard2067d1a2008-11-13 22:59:24 +0000544 }
545 }
Derek Jones63eeae32009-02-10 19:08:56 +0000546
Derek Allard2067d1a2008-11-13 22:59:24 +0000547 if (is_array($row['postdata']))
Derek Jones63eeae32009-02-10 19:08:56 +0000548 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000549 $array = array();
550 foreach ($row['postdata'] as $k => $v)
551 {
Andrey Andreevc2268712013-02-08 22:10:23 +0200552 $array[$k] = $v;
Derek Allard2067d1a2008-11-13 22:59:24 +0000553 }
Derek Jones63eeae32009-02-10 19:08:56 +0000554
555 $post_ref = $array;
Derek Allard2067d1a2008-11-13 22:59:24 +0000556 }
557 else
Derek Jones63eeae32009-02-10 19:08:56 +0000558 {
Andrey Andreevc2268712013-02-08 22:10:23 +0200559 $post_ref = $row['postdata'];
Derek Allard2067d1a2008-11-13 22:59:24 +0000560 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000561 }
562 }
563 }
564 }
565
566 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200567
Derek Allard2067d1a2008-11-13 22:59:24 +0000568 /**
569 * Executes the Validation routines
570 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000571 * @param array
572 * @param array
573 * @param mixed
Andrey Andreev78f55772012-04-03 19:59:08 +0300574 * @param int
Derek Allard2067d1a2008-11-13 22:59:24 +0000575 * @return mixed
Barry Mienydd671972010-10-04 16:33:58 +0200576 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100577 protected function _execute($row, $rules, $postdata = NULL, $cycles = 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000578 {
579 // If the $_POST data is an array we will run a recursive call
580 if (is_array($postdata))
Barry Mienydd671972010-10-04 16:33:58 +0200581 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000582 foreach ($postdata as $key => $val)
583 {
Andrey Andreev8d3099d2012-06-21 16:00:20 +0300584 $this->_execute($row, $rules, $val, $key);
Derek Allard2067d1a2008-11-13 22:59:24 +0000585 }
Barry Mienydd671972010-10-04 16:33:58 +0200586
Derek Allard2067d1a2008-11-13 22:59:24 +0000587 return;
588 }
Barry Mienydd671972010-10-04 16:33:58 +0200589
Derek Allard2067d1a2008-11-13 22:59:24 +0000590 // If the field is blank, but NOT required, no further tests are necessary
591 $callback = FALSE;
Hashem Qolami05370bf2013-07-22 01:52:04 +0430592 if ( ! in_array('required', $rules) && ($postdata === NULL OR $postdata === ''))
Derek Allard2067d1a2008-11-13 22:59:24 +0000593 {
594 // Before we bail out, does the rule contain a callback?
Andrey Andreev4b90a372014-03-10 10:24:24 +0200595 foreach ($rules as &$rule)
Derek Allard2067d1a2008-11-13 22:59:24 +0000596 {
Andrey Andreev4b90a372014-03-10 10:24:24 +0200597 if (is_string($rule))
598 {
599 if (strncmp($rule, 'callback_', 9) === 0)
600 {
601 $callback = TRUE;
602 $rules = array(1 => $rule);
603 break;
604 }
605 }
606 elseif (is_callable($rule))
607 {
608 $callback = TRUE;
609 $rules = array(1 => $rule);
610 break;
611 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000612 }
Andrey Andreev4b90a372014-03-10 10:24:24 +0200613
614 if ( ! $callback)
Derek Allard2067d1a2008-11-13 22:59:24 +0000615 {
616 return;
617 }
618 }
619
Derek Allard2067d1a2008-11-13 22:59:24 +0000620 // Isset Test. Typically this rule will only apply to checkboxes.
Andrey Andreev4b90a372014-03-10 10:24:24 +0200621 if (($postdata === NULL OR $postdata === '') && ! $callback)
Derek Allard2067d1a2008-11-13 22:59:24 +0000622 {
623 if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))
624 {
625 // Set the message type
Andrey Andreev78f55772012-04-03 19:59:08 +0300626 $type = in_array('required', $rules) ? 'required' : 'isset';
Barry Mienydd671972010-10-04 16:33:58 +0200627
Ahmedul Haque Abide9b0ccc2014-01-09 15:58:51 +0600628 // Check if a custom message is defined
Ahmedul Haque Abidea294882014-01-09 16:01:31 +0600629 if (isset($this->_field_data[$row['field']]['errors'][$type]))
Ahmedul Haque Abid42b40002014-01-09 01:10:25 +0600630 {
Ahmedul Haque Abidea294882014-01-09 16:01:31 +0600631 $line = $this->_field_data[$row['field']]['errors'][$type];
Ahmedul Haque Abid42b40002014-01-09 01:10:25 +0600632 }
633 elseif (isset($this->_error_messages[$type]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000634 {
635 $line = $this->_error_messages[$type];
636 }
Andrey Andreevd4eec9f2012-12-14 11:07:13 +0200637 elseif (FALSE === ($line = $this->CI->lang->line('form_validation_'.$type))
638 // DEPRECATED support for non-prefixed keys
639 && FALSE === ($line = $this->CI->lang->line($type, FALSE)))
Andrey Andreev56454792012-05-17 14:32:19 +0300640 {
641 $line = 'The field was not set';
642 }
Barry Mienydd671972010-10-04 16:33:58 +0200643
Derek Allard2067d1a2008-11-13 22:59:24 +0000644 // Build the error message
Eric Roberts41cc0902012-01-24 00:59:44 -0600645 $message = $this->_build_error_msg($line, $this->_translate_fieldname($row['label']));
Derek Allard2067d1a2008-11-13 22:59:24 +0000646
647 // Save the error message
648 $this->_field_data[$row['field']]['error'] = $message;
Barry Mienydd671972010-10-04 16:33:58 +0200649
Derek Allard2067d1a2008-11-13 22:59:24 +0000650 if ( ! isset($this->_error_array[$row['field']]))
651 {
652 $this->_error_array[$row['field']] = $message;
653 }
654 }
Barry Mienydd671972010-10-04 16:33:58 +0200655
Derek Allard2067d1a2008-11-13 22:59:24 +0000656 return;
657 }
658
659 // --------------------------------------------------------------------
660
661 // Cycle through each rule and run it
Andrey Andreev78f55772012-04-03 19:59:08 +0300662 foreach ($rules as $rule)
Derek Allard2067d1a2008-11-13 22:59:24 +0000663 {
664 $_in_array = FALSE;
Barry Mienydd671972010-10-04 16:33:58 +0200665
Derek Allard2067d1a2008-11-13 22:59:24 +0000666 // We set the $postdata variable with the current data in our master array so that
667 // each cycle of the loop is dealing with the processed data from the last cycle
Alex Bilbied261b1e2012-06-02 11:12:16 +0100668 if ($row['is_array'] === TRUE && is_array($this->_field_data[$row['field']]['postdata']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000669 {
670 // We shouldn't need this safety, but just in case there isn't an array index
671 // associated with this cycle we'll bail out
672 if ( ! isset($this->_field_data[$row['field']]['postdata'][$cycles]))
673 {
674 continue;
675 }
Barry Mienydd671972010-10-04 16:33:58 +0200676
Derek Allard2067d1a2008-11-13 22:59:24 +0000677 $postdata = $this->_field_data[$row['field']]['postdata'][$cycles];
678 $_in_array = TRUE;
679 }
680 else
681 {
Andrey Andreev6ac51442012-06-18 13:05:17 +0300682 // If we get an array field, but it's not expected - then it is most likely
683 // somebody messing with the form on the client side, so we'll just consider
684 // it an empty field
685 $postdata = is_array($this->_field_data[$row['field']]['postdata'])
Andrey Andreev4b90a372014-03-10 10:24:24 +0200686 ? NULL
687 : $this->_field_data[$row['field']]['postdata'];
Derek Allard2067d1a2008-11-13 22:59:24 +0000688 }
689
Barry Mienydd671972010-10-04 16:33:58 +0200690 // Is the rule a callback?
Andrey Andreev4b90a372014-03-10 10:24:24 +0200691 $callback = $callable = FALSE;
692 if (is_string($rule))
Derek Allard2067d1a2008-11-13 22:59:24 +0000693 {
Andrey Andreev4b90a372014-03-10 10:24:24 +0200694 if (strpos($rule, 'callback_') === 0)
695 {
696 $rule = substr($rule, 9);
697 $callback = TRUE;
698 }
699 }
700 elseif (is_callable($rule))
701 {
702 $callable = TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000703 }
Andrey Andreev60726ef2014-09-08 11:31:48 +0300704 elseif (is_array($rule) && isset($rule[0], $rule[1]) && is_callable($rule[1]))
705 {
706 // We have a "named" callable, so save the name
707 $callable = $rule[0];
708 $rule = $rule[1];
709 }
Barry Mienydd671972010-10-04 16:33:58 +0200710
Derek Allard2067d1a2008-11-13 22:59:24 +0000711 // Strip the parameter (if exists) from the rule
712 // Rules can contain a parameter: max_length[5]
713 $param = FALSE;
Andrey Andreev4b90a372014-03-10 10:24:24 +0200714 if ( ! $callable && preg_match('/(.*?)\[(.*)\]/', $rule, $match))
Derek Allard2067d1a2008-11-13 22:59:24 +0000715 {
Andrey Andreevef758bd2012-11-15 12:24:52 +0200716 $rule = $match[1];
717 $param = $match[2];
Derek Allard2067d1a2008-11-13 22:59:24 +0000718 }
Barry Mienydd671972010-10-04 16:33:58 +0200719
Derek Allard2067d1a2008-11-13 22:59:24 +0000720 // Call the function that corresponds to the rule
Andrey Andreev60726ef2014-09-08 11:31:48 +0300721 if ($callback OR $callable !== FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000722 {
Andrey Andreev4b90a372014-03-10 10:24:24 +0200723 if ($callback)
Barry Mienydd671972010-10-04 16:33:58 +0200724 {
Andrey Andreev4b90a372014-03-10 10:24:24 +0200725 if ( ! method_exists($this->CI, $rule))
726 {
727 log_message('debug', 'Unable to find callback validation rule: '.$rule);
728 $result = FALSE;
729 }
730 else
731 {
732 // Run the function and grab the result
733 $result = $this->CI->$rule($postdata, $param);
734 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000735 }
Andrey Andreev901573c2012-01-11 01:40:48 +0200736 else
737 {
Andrey Andreev4b90a372014-03-10 10:24:24 +0200738 $result = is_array($rule)
Andrey Andreev60726ef2014-09-08 11:31:48 +0300739 ? $rule[0]->{$rule[1]}($postdata)
740 : $rule($postdata);
741
742 // Is $callable set to a rule name?
743 if ($callable !== FALSE)
744 {
745 $rule = $callable;
746 }
Andrey Andreev901573c2012-01-11 01:40:48 +0200747 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000748
749 // Re-assign the result to the master data array
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200750 if ($_in_array === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000751 {
Andrey Andreev78f55772012-04-03 19:59:08 +0300752 $this->_field_data[$row['field']]['postdata'][$cycles] = is_bool($result) ? $postdata : $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000753 }
754 else
755 {
Andrey Andreev78f55772012-04-03 19:59:08 +0300756 $this->_field_data[$row['field']]['postdata'] = is_bool($result) ? $postdata : $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000757 }
Barry Mienydd671972010-10-04 16:33:58 +0200758
Derek Allard2067d1a2008-11-13 22:59:24 +0000759 // If the field isn't required and we just processed a callback we'll move on...
Andrey Andreev6de924c2012-01-20 13:18:18 +0200760 if ( ! in_array('required', $rules, TRUE) && $result !== FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000761 {
Derek Allard4e5cf1c2009-07-06 20:53:41 +0000762 continue;
Derek Allard2067d1a2008-11-13 22:59:24 +0000763 }
764 }
Andrey Andreev78f55772012-04-03 19:59:08 +0300765 elseif ( ! method_exists($this, $rule))
Barry Mienydd671972010-10-04 16:33:58 +0200766 {
Andrey Andreev78f55772012-04-03 19:59:08 +0300767 // If our own wrapper function doesn't exist we see if a native PHP function does.
768 // Users can use any native PHP function call that has one param.
769 if (function_exists($rule))
Derek Allard2067d1a2008-11-13 22:59:24 +0000770 {
Andrey Andreev4b90a372014-03-10 10:24:24 +0200771 // Native PHP functions issue warnings if you pass them more parameters than they use
Andrey Andreev320d37c2012-04-03 20:21:39 +0300772 $result = ($param !== FALSE) ? $rule($postdata, $param) : $rule($postdata);
Barry Mienydd671972010-10-04 16:33:58 +0200773
Andrey Andreev78f55772012-04-03 19:59:08 +0300774 if ($_in_array === TRUE)
775 {
776 $this->_field_data[$row['field']]['postdata'][$cycles] = is_bool($result) ? $postdata : $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000777 }
patwork02404a12011-04-08 15:45:46 +0200778 else
779 {
Andrey Andreevcec2ba52012-04-03 20:26:38 +0300780 $this->_field_data[$row['field']]['postdata'] = is_bool($result) ? $postdata : $result;
patwork02404a12011-04-08 15:45:46 +0200781 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000782 }
Andrey Andreev901573c2012-01-11 01:40:48 +0200783 else
784 {
Andrey Andreevcec2ba52012-04-03 20:26:38 +0300785 log_message('debug', 'Unable to find validation rule: '.$rule);
786 $result = FALSE;
Andrey Andreev901573c2012-01-11 01:40:48 +0200787 }
Andrey Andreev78f55772012-04-03 19:59:08 +0300788 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000789 else
790 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000791 $result = $this->$rule($postdata, $param);
792
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200793 if ($_in_array === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000794 {
Andrey Andreev78f55772012-04-03 19:59:08 +0300795 $this->_field_data[$row['field']]['postdata'][$cycles] = is_bool($result) ? $postdata : $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000796 }
797 else
798 {
Andrey Andreev78f55772012-04-03 19:59:08 +0300799 $this->_field_data[$row['field']]['postdata'] = is_bool($result) ? $postdata : $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000800 }
801 }
Barry Mienydd671972010-10-04 16:33:58 +0200802
Andrey Andreev901573c2012-01-11 01:40:48 +0200803 // Did the rule test negatively? If so, grab the error.
Derek Allard2067d1a2008-11-13 22:59:24 +0000804 if ($result === FALSE)
Barry Mienydd671972010-10-04 16:33:58 +0200805 {
Andrey Andreev60726ef2014-09-08 11:31:48 +0300806 // Callable rules might not have named error messages
Andrey Andreev57f10052014-06-07 12:22:37 +0300807 if ( ! is_string($rule))
Ahmedul Haque Abid42b40002014-01-09 01:10:25 +0600808 {
Andrey Andreev57f10052014-06-07 12:22:37 +0300809 return;
810 }
811
812 // Check if a custom message is defined
813 if (isset($this->_field_data[$row['field']]['errors'][$rule]))
814 {
815 $line = $this->_field_data[$row['field']]['errors'][$rule];
816 }
817 elseif ( ! isset($this->_error_messages[$rule]))
818 {
819 if (FALSE === ($line = $this->CI->lang->line('form_validation_'.$rule))
820 // DEPRECATED support for non-prefixed keys
821 && FALSE === ($line = $this->CI->lang->line($rule, FALSE)))
Derek Allard2067d1a2008-11-13 22:59:24 +0000822 {
Andrey Andreev57f10052014-06-07 12:22:37 +0300823 $line = 'Unable to access an error message corresponding to your field name.';
Barry Mienydd671972010-10-04 16:33:58 +0200824 }
Andrey Andreev57f10052014-06-07 12:22:37 +0300825 }
826 else
827 {
828 $line = $this->_error_messages[$rule];
Derek Allard2067d1a2008-11-13 22:59:24 +0000829 }
Barry Mienydd671972010-10-04 16:33:58 +0200830
Derek Allard2067d1a2008-11-13 22:59:24 +0000831 // Is the parameter we are inserting into the error message the name
Andrey Andreev901573c2012-01-11 01:40:48 +0200832 // of another field? If so we need to grab its "field label"
Andrey Andreev8dc532d2011-12-24 17:57:54 +0200833 if (isset($this->_field_data[$param], $this->_field_data[$param]['label']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000834 {
Pascal Krietec1895832009-10-13 12:56:43 +0000835 $param = $this->_translate_fieldname($this->_field_data[$param]['label']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000836 }
Barry Mienydd671972010-10-04 16:33:58 +0200837
Derek Allard2067d1a2008-11-13 22:59:24 +0000838 // Build the error message
Eric Roberts41cc0902012-01-24 00:59:44 -0600839 $message = $this->_build_error_msg($line, $this->_translate_fieldname($row['label']), $param);
Derek Allard2067d1a2008-11-13 22:59:24 +0000840
841 // Save the error message
842 $this->_field_data[$row['field']]['error'] = $message;
Barry Mienydd671972010-10-04 16:33:58 +0200843
Derek Allard2067d1a2008-11-13 22:59:24 +0000844 if ( ! isset($this->_error_array[$row['field']]))
845 {
846 $this->_error_array[$row['field']] = $message;
847 }
Barry Mienydd671972010-10-04 16:33:58 +0200848
Derek Allard2067d1a2008-11-13 22:59:24 +0000849 return;
850 }
851 }
852 }
853
854 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200855
Derek Allard2067d1a2008-11-13 22:59:24 +0000856 /**
857 * Translate a field name
858 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000859 * @param string the field name
860 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200861 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100862 protected function _translate_fieldname($fieldname)
Derek Allard2067d1a2008-11-13 22:59:24 +0000863 {
864 // Do we need to translate the field name?
865 // We look for the prefix lang: to determine this
Andrey Andreev7a7ad782012-11-12 17:21:01 +0200866 if (sscanf($fieldname, 'lang:%s', $line) === 1)
Derek Allard2067d1a2008-11-13 22:59:24 +0000867 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500868 // Were we able to translate the field name? If not we use $line
Andrey Andreevd4eec9f2012-12-14 11:07:13 +0200869 if (FALSE === ($fieldname = $this->CI->lang->line('form_validation_'.$line))
870 // DEPRECATED support for non-prefixed keys
871 && FALSE === ($fieldname = $this->CI->lang->line($line, FALSE)))
Derek Allard2067d1a2008-11-13 22:59:24 +0000872 {
873 return $line;
874 }
875 }
876
877 return $fieldname;
878 }
879
880 // --------------------------------------------------------------------
Andrey Andreevd4eec9f2012-12-14 11:07:13 +0200881
Eric Roberts41cc0902012-01-24 00:59:44 -0600882 /**
883 * Build an error message using the field and param.
884 *
885 * @param string The error message line
886 * @param string A field's human name
887 * @param mixed A rule's optional parameter
888 * @return string
889 */
890 protected function _build_error_msg($line, $field = '', $param = '')
891 {
892 // Check for %s in the string for legacy support.
Eric Roberts24a13f52012-12-12 07:09:42 -0600893 if (strpos($line, '%s') !== FALSE)
Eric Roberts41cc0902012-01-24 00:59:44 -0600894 {
895 return sprintf($line, $field, $param);
896 }
Andrew Podner4296a652012-12-17 07:51:15 -0500897
Eric Roberts41cc0902012-01-24 00:59:44 -0600898 return str_replace(array('{field}', '{param}'), array($field, $param), $line);
899 }
900
901 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200902
Derek Allard2067d1a2008-11-13 22:59:24 +0000903 /**
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530904 * Checks if the rule is present within the validator
905 *
906 * Permits you to check if a rule is present within the validator
907 *
908 * @param string the field name
909 * @return bool
910 */
911 public function has_rule($field)
912 {
913 return isset($this->_field_data[$field]);
914 }
915
916 // --------------------------------------------------------------------
917
918 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000919 * Get the value from a form
920 *
921 * Permits you to repopulate a form field with the value it was submitted
922 * with, or, if that value doesn't exist, with the default
923 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000924 * @param string the field name
925 * @param string
Andrey Andreev46ac8812012-02-28 14:32:54 +0200926 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200927 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100928 public function set_value($field = '', $default = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000929 {
Andrey Andreev46ac8812012-02-28 14:32:54 +0200930 if ( ! isset($this->_field_data[$field], $this->_field_data[$field]['postdata']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000931 {
932 return $default;
933 }
Barry Mienydd671972010-10-04 16:33:58 +0200934
Phil Sturgeon5c561802011-01-05 16:31:59 +0000935 // If the data is an array output them one at a time.
Greg Aker03abee32011-12-25 00:31:29 -0600936 // E.g: form_input('name[]', set_value('name[]');
Phil Sturgeon5c561802011-01-05 16:31:59 +0000937 if (is_array($this->_field_data[$field]['postdata']))
938 {
939 return array_shift($this->_field_data[$field]['postdata']);
940 }
Phil Sturgeonc3828712011-01-19 12:31:47 +0000941
Derek Allard2067d1a2008-11-13 22:59:24 +0000942 return $this->_field_data[$field]['postdata'];
943 }
Barry Mienydd671972010-10-04 16:33:58 +0200944
Derek Allard2067d1a2008-11-13 22:59:24 +0000945 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200946
Derek Allard2067d1a2008-11-13 22:59:24 +0000947 /**
948 * Set Select
949 *
950 * Enables pull-down lists to be set to the value the user
951 * selected in the event of an error
952 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000953 * @param string
954 * @param string
Timothy Warren0688ac92012-04-20 10:25:04 -0400955 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +0000956 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200957 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +0100958 public function set_select($field = '', $value = '', $default = FALSE)
Barry Mienydd671972010-10-04 16:33:58 +0200959 {
Andrey Andreev46ac8812012-02-28 14:32:54 +0200960 if ( ! isset($this->_field_data[$field], $this->_field_data[$field]['postdata']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000961 {
Andrey Andreev6de924c2012-01-20 13:18:18 +0200962 return ($default === TRUE && count($this->_field_data) === 0) ? ' selected="selected"' : '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000963 }
Barry Mienydd671972010-10-04 16:33:58 +0200964
Derek Allard2067d1a2008-11-13 22:59:24 +0000965 $field = $this->_field_data[$field]['postdata'];
Andrey Andreeva587a932013-10-23 19:57:46 +0300966 $value = (string) $value;
Derek Allard2067d1a2008-11-13 22:59:24 +0000967 if (is_array($field))
968 {
Andrey Andreeva587a932013-10-23 19:57:46 +0300969 // Note: in_array('', array(0)) returns TRUE, do not use it
970 foreach ($field as &$v)
Derek Allard2067d1a2008-11-13 22:59:24 +0000971 {
Andrey Andreeva587a932013-10-23 19:57:46 +0300972 if ($value === $v)
973 {
974 return ' selected="selected"';
975 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000976 }
Andrey Andreeva587a932013-10-23 19:57:46 +0300977
978 return '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000979 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100980 elseif (($field === '' OR $value === '') OR ($field !== $value))
Derek Allard2067d1a2008-11-13 22:59:24 +0000981 {
Andrey Andreev901573c2012-01-11 01:40:48 +0200982 return '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000983 }
Barry Mienydd671972010-10-04 16:33:58 +0200984
Derek Allard2067d1a2008-11-13 22:59:24 +0000985 return ' selected="selected"';
986 }
Barry Mienydd671972010-10-04 16:33:58 +0200987
Derek Allard2067d1a2008-11-13 22:59:24 +0000988 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200989
Derek Allard2067d1a2008-11-13 22:59:24 +0000990 /**
991 * Set Radio
992 *
993 * Enables radio buttons to be set to the value the user
994 * selected in the event of an error
995 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000996 * @param string
997 * @param string
Timothy Warren0688ac92012-04-20 10:25:04 -0400998 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +0000999 * @return string
Barry Mienydd671972010-10-04 16:33:58 +02001000 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001001 public function set_radio($field = '', $value = '', $default = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001002 {
Andrey Andreev46ac8812012-02-28 14:32:54 +02001003 if ( ! isset($this->_field_data[$field], $this->_field_data[$field]['postdata']))
Derek Allard2067d1a2008-11-13 22:59:24 +00001004 {
Andrey Andreev6de924c2012-01-20 13:18:18 +02001005 return ($default === TRUE && count($this->_field_data) === 0) ? ' checked="checked"' : '';
Derek Allard2067d1a2008-11-13 22:59:24 +00001006 }
Barry Mienydd671972010-10-04 16:33:58 +02001007
Derek Allard2067d1a2008-11-13 22:59:24 +00001008 $field = $this->_field_data[$field]['postdata'];
Andrey Andreeva587a932013-10-23 19:57:46 +03001009 $value = (string) $value;
Derek Allard2067d1a2008-11-13 22:59:24 +00001010 if (is_array($field))
1011 {
Andrey Andreeva587a932013-10-23 19:57:46 +03001012 // Note: in_array('', array(0)) returns TRUE, do not use it
1013 foreach ($field as &$v)
Derek Allard2067d1a2008-11-13 22:59:24 +00001014 {
Andrey Andreeva587a932013-10-23 19:57:46 +03001015 if ($value === $v)
1016 {
1017 return ' checked="checked"';
1018 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001019 }
Andrey Andreeva587a932013-10-23 19:57:46 +03001020
1021 return '';
Derek Allard2067d1a2008-11-13 22:59:24 +00001022 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001023 elseif (($field === '' OR $value === '') OR ($field !== $value))
Derek Allard2067d1a2008-11-13 22:59:24 +00001024 {
Andrey Andreev901573c2012-01-11 01:40:48 +02001025 return '';
Derek Allard2067d1a2008-11-13 22:59:24 +00001026 }
Barry Mienydd671972010-10-04 16:33:58 +02001027
Derek Allard2067d1a2008-11-13 22:59:24 +00001028 return ' checked="checked"';
1029 }
Barry Mienydd671972010-10-04 16:33:58 +02001030
Derek Allard2067d1a2008-11-13 22:59:24 +00001031 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001032
Derek Allard2067d1a2008-11-13 22:59:24 +00001033 /**
1034 * Set Checkbox
1035 *
1036 * Enables checkboxes to be set to the value the user
1037 * selected in the event of an error
1038 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001039 * @param string
1040 * @param string
Timothy Warren0688ac92012-04-20 10:25:04 -04001041 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +00001042 * @return string
Barry Mienydd671972010-10-04 16:33:58 +02001043 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001044 public function set_checkbox($field = '', $value = '', $default = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001045 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +02001046 // Logic is exactly the same as for radio fields
1047 return $this->set_radio($field, $value, $default);
Derek Allard2067d1a2008-11-13 22:59:24 +00001048 }
Barry Mienydd671972010-10-04 16:33:58 +02001049
Derek Allard2067d1a2008-11-13 22:59:24 +00001050 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001051
Derek Allard2067d1a2008-11-13 22:59:24 +00001052 /**
1053 * Required
1054 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001055 * @param string
1056 * @return bool
1057 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001058 public function required($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001059 {
Andrey Andreev78f55772012-04-03 19:59:08 +03001060 return is_array($str) ? (bool) count($str) : (trim($str) !== '');
Derek Allard2067d1a2008-11-13 22:59:24 +00001061 }
Barry Mienydd671972010-10-04 16:33:58 +02001062
Derek Allard2067d1a2008-11-13 22:59:24 +00001063 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001064
Derek Allard2067d1a2008-11-13 22:59:24 +00001065 /**
Dan Horrigan2280e8e2010-12-15 10:16:38 -05001066 * Performs a Regular Expression match test.
1067 *
Dan Horrigan2280e8e2010-12-15 10:16:38 -05001068 * @param string
Andrey Andreev78f55772012-04-03 19:59:08 +03001069 * @param string regex
Dan Horrigan2280e8e2010-12-15 10:16:38 -05001070 * @return bool
1071 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001072 public function regex_match($str, $regex)
Dan Horrigan2280e8e2010-12-15 10:16:38 -05001073 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +02001074 return (bool) preg_match($regex, $str);
Dan Horrigan2280e8e2010-12-15 10:16:38 -05001075 }
1076
1077 // --------------------------------------------------------------------
1078
1079 /**
Derek Allard2067d1a2008-11-13 22:59:24 +00001080 * Match one field to another
1081 *
Andrey Andreeva779b2c2012-10-26 16:25:47 +03001082 * @param string $str string to compare against
1083 * @param string $field
Derek Allard2067d1a2008-11-13 22:59:24 +00001084 * @return bool
1085 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001086 public function matches($str, $field)
Derek Allard2067d1a2008-11-13 22:59:24 +00001087 {
Andrey Andreeva779b2c2012-10-26 16:25:47 +03001088 return isset($this->_field_data[$field], $this->_field_data[$field]['postdata'])
1089 ? ($str === $this->_field_data[$field]['postdata'])
1090 : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001091 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001092
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001093 // --------------------------------------------------------------------
1094
1095 /**
Raul Baldner Juniorf38564d2012-10-11 11:32:23 -03001096 * Differs from another field
1097 *
1098 * @param string
1099 * @param string field
1100 * @return bool
1101 */
1102 public function differs($str, $field)
1103 {
1104 return ! (isset($this->_field_data[$field]) && $this->_field_data[$field]['postdata'] === $str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001105 }
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001106
1107 // --------------------------------------------------------------------
1108
1109 /**
Andrey Andreevd09d6502012-01-03 06:38:33 +02001110 * Is Unique
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001111 *
Andrey Andreevd09d6502012-01-03 06:38:33 +02001112 * Check if the input value doesn't already exist
1113 * in the specified database field.
1114 *
Andrey Andreev9a0e0c72014-04-09 15:10:27 +03001115 * @param string $str
1116 * @param string $field
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001117 * @return bool
1118 */
1119 public function is_unique($str, $field)
1120 {
Andrey Andreev7a7ad782012-11-12 17:21:01 +02001121 sscanf($field, '%[^.].%[^.]', $table, $field);
Andrey Andreev9a0e0c72014-04-09 15:10:27 +03001122 return isset($this->CI->db)
1123 ? ($this->CI->db->limit(1)->get_where($table, array($field => $str))->num_rows() === 0)
1124 : FALSE;
Greg Aker03abee32011-12-25 00:31:29 -06001125 }
Barry Mienydd671972010-10-04 16:33:58 +02001126
Derek Allard2067d1a2008-11-13 22:59:24 +00001127 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001128
Derek Allard2067d1a2008-11-13 22:59:24 +00001129 /**
1130 * Minimum Length
1131 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001132 * @param string
Michiel Vugteveena8221ad2012-06-14 23:26:34 +02001133 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +00001134 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001135 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001136 public function min_length($str, $val)
Derek Allard2067d1a2008-11-13 22:59:24 +00001137 {
Michiel Vugteveenceaf8872012-06-15 11:56:24 +02001138 if ( ! is_numeric($val))
Derek Allard2067d1a2008-11-13 22:59:24 +00001139 {
1140 return FALSE;
1141 }
1142
Andrey Andreev78f55772012-04-03 19:59:08 +03001143 return (MB_ENABLED === TRUE)
1144 ? ($val <= mb_strlen($str))
Michiel Vugteveenceaf8872012-06-15 11:56:24 +02001145 : ($val <= strlen($str));
Derek Allard2067d1a2008-11-13 22:59:24 +00001146 }
Barry Mienydd671972010-10-04 16:33:58 +02001147
Derek Allard2067d1a2008-11-13 22:59:24 +00001148 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001149
Derek Allard2067d1a2008-11-13 22:59:24 +00001150 /**
1151 * Max Length
1152 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001153 * @param string
Michiel Vugteveena8221ad2012-06-14 23:26:34 +02001154 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +00001155 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001156 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001157 public function max_length($str, $val)
Derek Allard2067d1a2008-11-13 22:59:24 +00001158 {
Michiel Vugteveenceaf8872012-06-15 11:56:24 +02001159 if ( ! is_numeric($val))
Derek Allard2067d1a2008-11-13 22:59:24 +00001160 {
1161 return FALSE;
1162 }
1163
Andrey Andreev78f55772012-04-03 19:59:08 +03001164 return (MB_ENABLED === TRUE)
1165 ? ($val >= mb_strlen($str))
1166 : ($val >= strlen($str));
Derek Allard2067d1a2008-11-13 22:59:24 +00001167 }
Barry Mienydd671972010-10-04 16:33:58 +02001168
Derek Allard2067d1a2008-11-13 22:59:24 +00001169 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001170
Derek Allard2067d1a2008-11-13 22:59:24 +00001171 /**
1172 * Exact Length
1173 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001174 * @param string
Michiel Vugteveeneccde132012-06-14 23:22:26 +02001175 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +00001176 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001177 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001178 public function exact_length($str, $val)
Derek Allard2067d1a2008-11-13 22:59:24 +00001179 {
Michiel Vugteveenceaf8872012-06-15 11:56:24 +02001180 if ( ! is_numeric($val))
Derek Allard2067d1a2008-11-13 22:59:24 +00001181 {
1182 return FALSE;
1183 }
1184
Andrey Andreev78f55772012-04-03 19:59:08 +03001185 return (MB_ENABLED === TRUE)
Andrey Andreev9a0e0c72014-04-09 15:10:27 +03001186 ? (mb_strlen($str) === (int) $val)
1187 : (strlen($str) === (int) $val);
Derek Allard2067d1a2008-11-13 22:59:24 +00001188 }
Barry Mienydd671972010-10-04 16:33:58 +02001189
Derek Allard2067d1a2008-11-13 22:59:24 +00001190 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001191
Derek Allard2067d1a2008-11-13 22:59:24 +00001192 /**
Andrey Andreevdaaca882012-11-26 22:16:12 +02001193 * Valid URL
1194 *
1195 * @param string $str
1196 * @return bool
1197 */
1198 public function valid_url($str)
1199 {
1200 if (empty($str))
1201 {
1202 return FALSE;
1203 }
1204 elseif (preg_match('/^(?:([^:]*)\:)?\/\/(.+)$/', $str, $matches))
1205 {
1206 if (empty($matches[2]))
1207 {
1208 return FALSE;
1209 }
1210 elseif ( ! in_array($matches[1], array('http', 'https'), TRUE))
1211 {
1212 return FALSE;
1213 }
1214
1215 $str = $matches[2];
1216 }
1217
1218 $str = 'http://'.$str;
1219
1220 // There's a bug affecting PHP 5.2.13, 5.3.2 that considers the
1221 // underscore to be a valid hostname character instead of a dash.
1222 // Reference: https://bugs.php.net/bug.php?id=51192
Andrey Andreev9a0e0c72014-04-09 15:10:27 +03001223 if (version_compare(PHP_VERSION, '5.2.13', '==') OR version_compare(PHP_VERSION, '5.3.2', '=='))
Andrey Andreevdaaca882012-11-26 22:16:12 +02001224 {
1225 sscanf($str, 'http://%[^/]', $host);
1226 $str = substr_replace($str, strtr($host, array('_' => '-', '-' => '_')), 7, strlen($host));
1227 }
1228
1229 return (filter_var($str, FILTER_VALIDATE_URL) !== FALSE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001230 }
1231
1232 // --------------------------------------------------------------------
1233
1234 /**
1235 * Valid Email
1236 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001237 * @param string
1238 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001239 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001240 public function valid_email($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001241 {
Andrey Andreevf9201ae2014-06-01 12:57:30 +03001242 if (function_exists('idn_to_ascii') && $atpos = strpos($str, '@'))
Andrey Andreev95496662014-06-01 00:00:13 +03001243 {
Andrey Andreevf9201ae2014-06-01 12:57:30 +03001244 $str = substr($str, 0, ++$atpos).idn_to_ascii(substr($str, $atpos));
Andrey Andreev95496662014-06-01 00:00:13 +03001245 }
1246
Andrey Andreev580388b2012-06-27 15:43:46 +03001247 return (bool) filter_var($str, FILTER_VALIDATE_EMAIL);
Derek Allard2067d1a2008-11-13 22:59:24 +00001248 }
1249
1250 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001251
Derek Allard2067d1a2008-11-13 22:59:24 +00001252 /**
1253 * Valid Emails
1254 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001255 * @param string
1256 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001257 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001258 public function valid_emails($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001259 {
1260 if (strpos($str, ',') === FALSE)
1261 {
1262 return $this->valid_email(trim($str));
1263 }
Barry Mienydd671972010-10-04 16:33:58 +02001264
Pascal Kriete14287f32011-02-14 13:39:34 -05001265 foreach (explode(',', $str) as $email)
Derek Allard2067d1a2008-11-13 22:59:24 +00001266 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +02001267 if (trim($email) !== '' && $this->valid_email(trim($email)) === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001268 {
1269 return FALSE;
1270 }
1271 }
Barry Mienydd671972010-10-04 16:33:58 +02001272
Derek Allard2067d1a2008-11-13 22:59:24 +00001273 return TRUE;
1274 }
1275
1276 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001277
Derek Allard2067d1a2008-11-13 22:59:24 +00001278 /**
1279 * Validate IP Address
1280 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001281 * @param string
Andrey Andreev5a257182012-06-10 06:18:14 +03001282 * @param string 'ipv4' or 'ipv6' to validate a specific IP format
Bo-Yi Wu013c8952011-09-12 15:03:44 +08001283 * @return bool
Derek Allard2067d1a2008-11-13 22:59:24 +00001284 */
Andrey Andreev5a257182012-06-10 06:18:14 +03001285 public function valid_ip($ip, $which = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001286 {
Andrey Andreev5a257182012-06-10 06:18:14 +03001287 return $this->CI->input->valid_ip($ip, $which);
Derek Allard2067d1a2008-11-13 22:59:24 +00001288 }
1289
1290 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001291
Derek Allard2067d1a2008-11-13 22:59:24 +00001292 /**
1293 * Alpha
1294 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001295 * @param string
1296 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001297 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001298 public function alpha($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001299 {
Andrey Andreevacb962e2012-06-27 12:04:24 +03001300 return ctype_alpha($str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001301 }
Barry Mienydd671972010-10-04 16:33:58 +02001302
Derek Allard2067d1a2008-11-13 22:59:24 +00001303 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001304
Derek Allard2067d1a2008-11-13 22:59:24 +00001305 /**
1306 * Alpha-numeric
1307 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001308 * @param string
1309 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001310 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001311 public function alpha_numeric($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001312 {
Andrey Andreevacb962e2012-06-27 12:04:24 +03001313 return ctype_alnum((string) $str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001314 }
Barry Mienydd671972010-10-04 16:33:58 +02001315
Derek Allard2067d1a2008-11-13 22:59:24 +00001316 // --------------------------------------------------------------------
Sajan Parikh2d1608a2013-02-02 08:00:39 -06001317
1318 /**
1319 * Alpha-numeric w/ spaces
1320 *
1321 * @param string
1322 * @return bool
1323 */
1324 public function alpha_numeric_spaces($str)
1325 {
Sajan Parikhdf3bfed2013-02-04 12:25:49 -06001326 return (bool) preg_match('/^[A-Z0-9 ]+$/i', $str);
Sajan Parikh2d1608a2013-02-02 08:00:39 -06001327 }
1328
1329 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001330
Derek Allard2067d1a2008-11-13 22:59:24 +00001331 /**
1332 * Alpha-numeric with underscores and dashes
1333 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001334 * @param string
1335 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001336 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001337 public function alpha_dash($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001338 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +02001339 return (bool) preg_match('/^[a-z0-9_-]+$/i', $str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001340 }
Barry Mienydd671972010-10-04 16:33:58 +02001341
Derek Allard2067d1a2008-11-13 22:59:24 +00001342 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001343
Derek Allard2067d1a2008-11-13 22:59:24 +00001344 /**
1345 * Numeric
1346 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001347 * @param string
1348 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001349 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001350 public function numeric($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001351 {
Andrey Andreev8dc532d2011-12-24 17:57:54 +02001352 return (bool) preg_match('/^[\-+]?[0-9]*\.?[0-9]+$/', $str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001353
1354 }
1355
1356 // --------------------------------------------------------------------
1357
Barry Mienydd671972010-10-04 16:33:58 +02001358 /**
Derek Allard2067d1a2008-11-13 22:59:24 +00001359 * Integer
1360 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001361 * @param string
1362 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +02001363 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001364 public function integer($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001365 {
Phil Sturgeonef112c02011-02-07 13:01:47 +00001366 return (bool) preg_match('/^[\-+]?[0-9]+$/', $str);
1367 }
1368
1369 // --------------------------------------------------------------------
1370
1371 /**
1372 * Decimal number
1373 *
Phil Sturgeonef112c02011-02-07 13:01:47 +00001374 * @param string
1375 * @return bool
1376 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001377 public function decimal($str)
Phil Sturgeonef112c02011-02-07 13:01:47 +00001378 {
1379 return (bool) preg_match('/^[\-+]?[0-9]+\.[0-9]+$/', $str);
1380 }
1381
1382 // --------------------------------------------------------------------
1383
1384 /**
Andrey Andreevc68905a2012-02-02 21:41:54 +02001385 * Greater than
Phil Sturgeonef112c02011-02-07 13:01:47 +00001386 *
Phil Sturgeonef112c02011-02-07 13:01:47 +00001387 * @param string
Timothy Warren0688ac92012-04-20 10:25:04 -04001388 * @param int
Phil Sturgeonef112c02011-02-07 13:01:47 +00001389 * @return bool
1390 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001391 public function greater_than($str, $min)
Phil Sturgeonef112c02011-02-07 13:01:47 +00001392 {
Andrey Andreev78f55772012-04-03 19:59:08 +03001393 return is_numeric($str) ? ($str > $min) : FALSE;
Phil Sturgeonef112c02011-02-07 13:01:47 +00001394 }
1395
1396 // --------------------------------------------------------------------
1397
1398 /**
Nick Busey98c347d2012-02-02 11:07:03 -07001399 * Equal to or Greater than
1400 *
Nick Busey98c347d2012-02-02 11:07:03 -07001401 * @param string
Timothy Warren0688ac92012-04-20 10:25:04 -04001402 * @param int
Nick Busey98c347d2012-02-02 11:07:03 -07001403 * @return bool
1404 */
Andrey Andreev3b2c5082012-03-07 22:49:24 +02001405 public function greater_than_equal_to($str, $min)
Nick Busey98c347d2012-02-02 11:07:03 -07001406 {
Andrey Andreev78f55772012-04-03 19:59:08 +03001407 return is_numeric($str) ? ($str >= $min) : FALSE;
Phil Sturgeonef112c02011-02-07 13:01:47 +00001408 }
1409
1410 // --------------------------------------------------------------------
1411
1412 /**
1413 * Less than
1414 *
Phil Sturgeonef112c02011-02-07 13:01:47 +00001415 * @param string
Timothy Warren0688ac92012-04-20 10:25:04 -04001416 * @param int
Phil Sturgeonef112c02011-02-07 13:01:47 +00001417 * @return bool
1418 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001419 public function less_than($str, $max)
Phil Sturgeonef112c02011-02-07 13:01:47 +00001420 {
Andrey Andreev78f55772012-04-03 19:59:08 +03001421 return is_numeric($str) ? ($str < $max) : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001422 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001423
1424 // --------------------------------------------------------------------
1425
Barry Mienydd671972010-10-04 16:33:58 +02001426 /**
Nick Busey98c347d2012-02-02 11:07:03 -07001427 * Equal to or Less than
1428 *
Nick Busey98c347d2012-02-02 11:07:03 -07001429 * @param string
Timothy Warren0688ac92012-04-20 10:25:04 -04001430 * @param int
Nick Busey98c347d2012-02-02 11:07:03 -07001431 * @return bool
1432 */
Andrey Andreev3b2c5082012-03-07 22:49:24 +02001433 public function less_than_equal_to($str, $max)
Nick Busey98c347d2012-02-02 11:07:03 -07001434 {
Andrey Andreev78f55772012-04-03 19:59:08 +03001435 return is_numeric($str) ? ($str <= $max) : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001436 }
1437
1438 // --------------------------------------------------------------------
1439
Barry Mienydd671972010-10-04 16:33:58 +02001440 /**
Lance Vincenteca885d2015-01-28 17:43:23 +08001441 * Value should be within an array of values
1442 *
1443 * @param string
1444 * @param array
1445 * @return bool
1446 */
1447 public function in($value, $list)
1448 {
1449 $list = array_map('trim', explode(',', (string) $list));
1450
1451 return in_array((string) $value, $list);
1452 }
1453
1454 // --------------------------------------------------------------------
1455
1456 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -05001457 * Is a Natural number (0,1,2,3, etc.)
Barry Mienydd671972010-10-04 16:33:58 +02001458 *
Barry Mienydd671972010-10-04 16:33:58 +02001459 * @param string
1460 * @return bool
1461 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001462 public function is_natural($str)
Barry Mienydd671972010-10-04 16:33:58 +02001463 {
Andrey Andreevacb962e2012-06-27 12:04:24 +03001464 return ctype_digit((string) $str);
Barry Mienydd671972010-10-04 16:33:58 +02001465 }
1466
1467 // --------------------------------------------------------------------
1468
1469 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -05001470 * Is a Natural number, but not a zero (1,2,3, etc.)
Barry Mienydd671972010-10-04 16:33:58 +02001471 *
Barry Mienydd671972010-10-04 16:33:58 +02001472 * @param string
1473 * @return bool
1474 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001475 public function is_natural_no_zero($str)
Barry Mienydd671972010-10-04 16:33:58 +02001476 {
Andrey Andreevacb962e2012-06-27 12:04:24 +03001477 return ($str != 0 && ctype_digit((string) $str));
Barry Mienydd671972010-10-04 16:33:58 +02001478 }
1479
Derek Allard2067d1a2008-11-13 22:59:24 +00001480 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001481
Derek Allard2067d1a2008-11-13 22:59:24 +00001482 /**
1483 * Valid Base64
1484 *
1485 * Tests a string for characters outside of the Base64 alphabet
1486 * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045
1487 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001488 * @param string
1489 * @return bool
1490 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001491 public function valid_base64($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001492 {
Andrey Andreevcd9797a2013-06-28 14:03:48 +03001493 return (base64_encode(base64_decode($str)) === $str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001494 }
Barry Mienydd671972010-10-04 16:33:58 +02001495
Derek Allard2067d1a2008-11-13 22:59:24 +00001496 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001497
Derek Allard2067d1a2008-11-13 22:59:24 +00001498 /**
1499 * Prep data for form
1500 *
1501 * This function allows HTML to be safely shown in a form.
1502 * Special characters are converted.
1503 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001504 * @param string
1505 * @return string
1506 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001507 public function prep_for_form($data = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001508 {
Andrey Andreev7c4d1062012-11-01 15:14:34 +02001509 if ($this->_safe_form_data === FALSE OR empty($data))
1510 {
1511 return $data;
1512 }
1513
Derek Allard2067d1a2008-11-13 22:59:24 +00001514 if (is_array($data))
1515 {
1516 foreach ($data as $key => $val)
1517 {
1518 $data[$key] = $this->prep_for_form($val);
1519 }
Barry Mienydd671972010-10-04 16:33:58 +02001520
Derek Allard2067d1a2008-11-13 22:59:24 +00001521 return $data;
1522 }
Barry Mienydd671972010-10-04 16:33:58 +02001523
Andrey Andreev901573c2012-01-11 01:40:48 +02001524 return str_replace(array("'", '"', '<', '>'), array('&#39;', '&quot;', '&lt;', '&gt;'), stripslashes($data));
Derek Allard2067d1a2008-11-13 22:59:24 +00001525 }
Barry Mienydd671972010-10-04 16:33:58 +02001526
Derek Allard2067d1a2008-11-13 22:59:24 +00001527 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001528
Derek Allard2067d1a2008-11-13 22:59:24 +00001529 /**
1530 * Prep URL
1531 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001532 * @param string
1533 * @return string
Barry Mienydd671972010-10-04 16:33:58 +02001534 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001535 public function prep_url($str = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001536 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001537 if ($str === 'http://' OR $str === '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001538 {
1539 return '';
1540 }
Barry Mienydd671972010-10-04 16:33:58 +02001541
Andrey Andreev901573c2012-01-11 01:40:48 +02001542 if (strpos($str, 'http://') !== 0 && strpos($str, 'https://') !== 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001543 {
Andrey Andreev901573c2012-01-11 01:40:48 +02001544 return 'http://'.$str;
Derek Allard2067d1a2008-11-13 22:59:24 +00001545 }
Barry Mienydd671972010-10-04 16:33:58 +02001546
Derek Allard2067d1a2008-11-13 22:59:24 +00001547 return $str;
1548 }
Barry Mienydd671972010-10-04 16:33:58 +02001549
Derek Allard2067d1a2008-11-13 22:59:24 +00001550 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001551
Derek Allard2067d1a2008-11-13 22:59:24 +00001552 /**
1553 * Strip Image Tags
1554 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001555 * @param string
1556 * @return string
Barry Mienydd671972010-10-04 16:33:58 +02001557 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001558 public function strip_image_tags($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001559 {
Andrey Andreev1a24a9d2012-06-27 00:52:47 +03001560 return $this->CI->security->strip_image_tags($str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001561 }
Barry Mienydd671972010-10-04 16:33:58 +02001562
Derek Allard2067d1a2008-11-13 22:59:24 +00001563 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001564
Derek Allard2067d1a2008-11-13 22:59:24 +00001565 /**
1566 * XSS Clean
1567 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001568 * @param string
1569 * @return string
Barry Mienydd671972010-10-04 16:33:58 +02001570 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001571 public function xss_clean($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001572 {
Derek Jones5640a712010-04-23 11:22:40 -05001573 return $this->CI->security->xss_clean($str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001574 }
Barry Mienydd671972010-10-04 16:33:58 +02001575
Derek Allard2067d1a2008-11-13 22:59:24 +00001576 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001577
Derek Allard2067d1a2008-11-13 22:59:24 +00001578 /**
1579 * Convert PHP tags to entities
1580 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001581 * @param string
1582 * @return string
Barry Mienydd671972010-10-04 16:33:58 +02001583 */
Phil Sturgeon3837ae72011-05-09 21:12:26 +01001584 public function encode_php_tags($str)
Derek Allard2067d1a2008-11-13 22:59:24 +00001585 {
Andrey Andreev838a9d62012-12-03 14:37:47 +02001586 return str_replace(array('<?', '?>'), array('&lt;?', '?&gt;'), $str);
Derek Allard2067d1a2008-11-13 22:59:24 +00001587 }
1588
JonoB099c4782012-03-04 14:37:30 +00001589 // --------------------------------------------------------------------
Andrey Andreevc8da4fe2012-03-04 19:20:33 +02001590
1591 /**
1592 * Reset validation vars
1593 *
1594 * Prevents subsequent validation routines from being affected by the
JonoB099c4782012-03-04 14:37:30 +00001595 * results of any previous validation routine due to the CI singleton.
Andrey Andreevc8da4fe2012-03-04 19:20:33 +02001596 *
Andrey Andreeva89c1da2014-02-08 19:03:35 +02001597 * @return CI_Form_validation
Andrey Andreevc8da4fe2012-03-04 19:20:33 +02001598 */
JonoB883f80f2012-03-05 09:51:27 +00001599 public function reset_validation()
Andrey Andreevc8da4fe2012-03-04 19:20:33 +02001600 {
JonoB099c4782012-03-04 14:37:30 +00001601 $this->_field_data = array();
1602 $this->_config_rules = array();
1603 $this->_error_array = array();
1604 $this->_error_messages = array();
1605 $this->error_string = '';
Andrey Andreeva89c1da2014-02-08 19:03:35 +02001606 return $this;
Andrey Andreevc8da4fe2012-03-04 19:20:33 +02001607 }
1608
Derek Allard2067d1a2008-11-13 22:59:24 +00001609}
Derek Allard2067d1a2008-11-13 22:59:24 +00001610
1611/* End of file Form_validation.php */
Eric Roberts24a13f52012-12-12 07:09:42 -06001612/* Location: ./system/libraries/Form_validation.php */