Improve the Form validation library
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index 918f690..8173c6e 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -1,4 +1,4 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
@@ -86,7 +86,7 @@
 	public function set_rules($field, $label = '', $rules = '')
 	{
 		// No reason to set rules if we have no POST data
-		if (count($_POST) == 0)
+		if (count($_POST) === 0)
 		{
 			return $this;
 		}
@@ -113,7 +113,7 @@
 		}
 
 		// No fields? Nothing to do...
-		if ( ! is_string($field) OR  ! is_string($rules) OR $field == '')
+		if ( ! is_string($field) OR ! is_string($rules) OR $field == '')
 		{
 			return $this;
 		}
@@ -121,21 +121,20 @@
 		// If the field label wasn't passed we use the field name
 		$label = ($label == '') ? $field : $label;
 
-		// Is the field name an array?  We test for the existence of a bracket "[" in
-		// the field name to determine this.  If it is an array, we break it apart
+		// Is the field name an array? If it is an array, we break it apart
 		// into its components so that we can fetch the corresponding POST data later
-		if (strpos($field, '[') !== FALSE AND preg_match_all('/\[(.*?)\]/', $field, $matches))
+		if (preg_match_all('/\[(.*?)\]/', $field, $matches))
 		{
 			// Note: Due to a bug in current() that affects some versions
 			// of PHP we can not pass function call directly into it
 			$x = explode('[', $field);
 			$indexes[] = current($x);
 
-			for ($i = 0; $i < count($matches['0']); $i++)
+			for ($i = 0, $c = count($matches[0]); $i < $c; $i++)
 			{
-				if ($matches['1'][$i] != '')
+				if ($matches[1][$i] != '')
 				{
-					$indexes[] = $matches['1'][$i];
+					$indexes[] = $matches[1][$i];
 				}
 			}
 
@@ -293,17 +292,17 @@
 	public function run($group = '')
 	{
 		// Do we even have any data to process?  Mm?
-		if (count($_POST) == 0)
+		if (count($_POST) === 0)
 		{
 			return FALSE;
 		}
 
 		// Does the _field_data array containing the validation rules exist?
 		// If not, we look to see if they were assigned via a config file
-		if (count($this->_field_data) == 0)
+		if (count($this->_field_data) === 0)
 		{
 			// No validation rules?  We're done...
-			if (count($this->_config_rules) == 0)
+			if (count($this->_config_rules) === 0)
 			{
 				return FALSE;
 			}
@@ -321,7 +320,7 @@
 			}
 
 			// We're we able to set the rules correctly?
-			if (count($this->_field_data) == 0)
+			if (count($this->_field_data) === 0)
 			{
 				log_message('debug', "Unable to find validation rules");
 				return FALSE;
@@ -338,7 +337,7 @@
 			// Fetch the data from the corresponding $_POST array and cache it in the _field_data array.
 			// Depending on whether the field name is an array or a string will determine where we get it from.
 
-			if ($row['is_array'] == TRUE)
+			if ($row['is_array'] === TRUE)
 			{
 				$this->_field_data[$field]['postdata'] = $this->_reduce_array($_POST, $row['keys']);
 			}
@@ -364,14 +363,7 @@
 		// Now we need to re-set the POST data with the new, processed data
 		$this->_reset_post_array();
 
-		// No errors, validation passes!
-		if ($total_errors == 0)
-		{
-			return TRUE;
-		}
-
-		// Validation fails
-		return FALSE;
+		return ($total_errors === 0);
 	}
 
 	// --------------------------------------------------------------------
@@ -379,7 +371,7 @@
 	/**
 	 * Traverse a multidimensional $_POST array index until the data is found
 	 *
-	 * @access	private
+	 * @access	protected
 	 * @param	array
 	 * @param	array
 	 * @param	integer
@@ -387,23 +379,9 @@
 	 */
 	protected function _reduce_array($array, $keys, $i = 0)
 	{
-		if (is_array($array))
+		if (is_array($array) && isset($keys[$i]))
 		{
-			if (isset($keys[$i]))
-			{
-				if (isset($array[$keys[$i]]))
-				{
-					$array = $this->_reduce_array($array[$keys[$i]], $keys, ($i+1));
-				}
-				else
-				{
-					return NULL;
-				}
-			}
-			else
-			{
-				return $array;
-			}
+			return isset($array[$keys[$i]]) ? $this->_reduce_array($array[$keys[$i]], $keys, ($i+1)) : NULL;
 		}
 
 		return $array;
@@ -414,7 +392,7 @@
 	/**
 	 * Re-populate the _POST array with our finalized and processed data
 	 *
-	 * @access	private
+	 * @access	protected
 	 * @return	null
 	 */
 	protected function _reset_post_array()
@@ -423,7 +401,7 @@
 		{
 			if ( ! is_null($row['postdata']))
 			{
-				if ($row['is_array'] == FALSE)
+				if ($row['is_array'] === FALSE)
 				{
 					if (isset($_POST[$row['field']]))
 					{
@@ -436,7 +414,7 @@
 					$post_ref =& $_POST;
 
 					// before we assign values, make a reference to the right POST key
-					if (count($row['keys']) == 1)
+					if (count($row['keys']) === 1)
 					{
 						$post_ref =& $post_ref[current($row['keys'])];
 					}
@@ -472,7 +450,7 @@
 	/**
 	 * Executes the Validation routines
 	 *
-	 * @access	private
+	 * @access	protected
 	 * @param	array
 	 * @param	array
 	 * @param	mixed
@@ -514,7 +492,7 @@
 		// --------------------------------------------------------------------
 
 		// Isset Test. Typically this rule will only apply to checkboxes.
-		if (is_null($postdata) AND $callback == FALSE)
+		if (is_null($postdata) AND $callback === FALSE)
 		{
 			if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))
 			{
@@ -605,7 +583,7 @@
 				$result = $this->CI->$rule($postdata, $param);
 
 				// Re-assign the result to the master data array
-				if ($_in_array == TRUE)
+				if ($_in_array === TRUE)
 				{
 					$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
 				}
@@ -630,7 +608,7 @@
 					{
 						$result = $rule($postdata);
 
-						if ($_in_array == TRUE)
+						if ($_in_array === TRUE)
 						{
 							$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
 						}
@@ -649,7 +627,7 @@
 
 				$result = $this->$rule($postdata, $param);
 
-				if ($_in_array == TRUE)
+				if ($_in_array === TRUE)
 				{
 					$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
 				}
@@ -676,7 +654,7 @@
 
 				// Is the parameter we are inserting into the error message the name
 				// of another field?  If so we need to grab its "field label"
-				if (isset($this->_field_data[$param]) AND isset($this->_field_data[$param]['label']))
+				if (isset($this->_field_data[$param], $this->_field_data[$param]['label']))
 				{
 					$param = $this->_translate_fieldname($this->_field_data[$param]['label']);
 				}
@@ -702,7 +680,7 @@
 	/**
 	 * Translate a field name
 	 *
-	 * @access	private
+	 * @access	protected
 	 * @param	string	the field name
 	 * @return	string
 	 */
@@ -710,7 +688,7 @@
 	{
 		// Do we need to translate the field name?
 		// We look for the prefix lang: to determine this
-		if (substr($fieldname, 0, 5) == 'lang:')
+		if (substr($fieldname, 0, 5) === 'lang:')
 		{
 			// Grab the variable
 			$line = substr($fieldname, 5);
@@ -858,33 +836,8 @@
 	 */
 	public function set_checkbox($field = '', $value = '', $default = FALSE)
 	{
-		if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))
-		{
-			if ($default === TRUE AND count($this->_field_data) === 0)
-			{
-				return ' checked="checked"';
-			}
-			return '';
-		}
-
-		$field = $this->_field_data[$field]['postdata'];
-
-		if (is_array($field))
-		{
-			if ( ! in_array($value, $field))
-			{
-				return '';
-			}
-		}
-		else
-		{
-			if (($field == '' OR $value == '') OR ($field != $value))
-			{
-				return '';
-			}
-		}
-
-		return ' checked="checked"';
+		// Logic is exactly the same as for radio fields
+		return $this->set_radio($field, $value, $default);
 	}
 
 	// --------------------------------------------------------------------
@@ -898,14 +851,7 @@
 	 */
 	public function required($str)
 	{
-		if ( ! is_array($str))
-		{
-			return (trim($str) == '') ? FALSE : TRUE;
-		}
-		else
-		{
-			return ( ! empty($str));
-		}
+		return ( ! is_array($str)) ? (trim($str) !== '') : ( ! empty($str));
 	}
 
 	// --------------------------------------------------------------------
@@ -920,12 +866,7 @@
 	 */
 	public function regex_match($str, $regex)
 	{
-		if ( ! preg_match($regex, $str))
-		{
-			return FALSE;
-		}
-
-		return  TRUE;
+		return (bool) preg_match($regex, $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -947,7 +888,7 @@
 
 		$field = $_POST[$field];
 
-		return ($str !== $field) ? FALSE : TRUE;
+		return ($str === $field);
 	}
 
 	// --------------------------------------------------------------------
@@ -969,7 +910,7 @@
 			return $query->num_rows() === 0;
 		}
 		return FALSE;
-    }
+	}
 
 	// --------------------------------------------------------------------
 
@@ -990,10 +931,10 @@
 
 		if (function_exists('mb_strlen'))
 		{
-			return (mb_strlen($str) < $val) ? FALSE : TRUE;
+			return ! (mb_strlen($str) < $val);
 		}
 
-		return (strlen($str) < $val) ? FALSE : TRUE;
+		return ! (strlen($str) < $val);
 	}
 
 	// --------------------------------------------------------------------
@@ -1015,10 +956,10 @@
 
 		if (function_exists('mb_strlen'))
 		{
-			return (mb_strlen($str) > $val) ? FALSE : TRUE;
+			return ! (mb_strlen($str) > $val);
 		}
 
-		return (strlen($str) > $val) ? FALSE : TRUE;
+		return ! (strlen($str) > $val);
 	}
 
 	// --------------------------------------------------------------------
@@ -1040,10 +981,10 @@
 
 		if (function_exists('mb_strlen'))
 		{
-			return (mb_strlen($str) != $val) ? FALSE : TRUE;
+			return (mb_strlen($str) == $val);
 		}
 
-		return (strlen($str) != $val) ? FALSE : TRUE;
+		return (strlen($str) == $val);
 	}
 
 	// --------------------------------------------------------------------
@@ -1057,7 +998,7 @@
 	 */
 	public function valid_email($str)
 	{
-		return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
+		return (bool) preg_match('/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix', $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -1078,7 +1019,7 @@
 
 		foreach (explode(',', $str) as $email)
 		{
-			if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)
+			if (trim($email) !== '' && $this->valid_email(trim($email)) === FALSE)
 			{
 				return FALSE;
 			}
@@ -1112,7 +1053,7 @@
 	 */
 	public function alpha($str)
 	{
-		return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE;
+		return (bool) preg_match('/^[a-z]+$/i', $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -1126,7 +1067,7 @@
 	 */
 	public function alpha_numeric($str)
 	{
-		return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE;
+		return (bool) preg_match('/^[a-z0-9]+$/i', $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -1140,7 +1081,7 @@
 	 */
 	public function alpha_dash($str)
 	{
-		return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;
+		return (bool) preg_match('/^[a-z0-9_-]+$/i', $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -1154,7 +1095,7 @@
 	 */
 	public function numeric($str)
 	{
-		return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);
+		return (bool) preg_match('/^[\-+]?[0-9]*\.?[0-9]+$/', $str);
 
 	}
 
@@ -1169,7 +1110,7 @@
 	 */
 	public function is_numeric($str)
 	{
-		return ( ! is_numeric($str)) ? FALSE : TRUE;
+		return is_numeric($str);
 	}
 
 	// --------------------------------------------------------------------
@@ -1247,7 +1188,7 @@
 	 */
 	public function is_natural($str)
 	{
-		return (bool) preg_match( '/^[0-9]+$/', $str);
+		return (bool) preg_match('/^[0-9]+$/', $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -1261,17 +1202,7 @@
 	 */
 	public function is_natural_no_zero($str)
 	{
-		if ( ! preg_match( '/^[0-9]+$/', $str))
-		{
-			return FALSE;
-		}
-
-		if ($str == 0)
-		{
-			return FALSE;
-		}
-
-		return TRUE;
+		return ($str != 0 AND preg_match('/^[0-9]+$/', $str));
 	}
 
 	// --------------------------------------------------------------------
@@ -1339,7 +1270,7 @@
 			return '';
 		}
 
-		if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')
+		if (substr($str, 0, 7) !== 'http://' && substr($str, 0, 8) !== 'https://')
 		{
 			$str = 'http://'.$str;
 		}