Created
March 5, 2014 14:38
-
-
Save narfbg/9368385 to your computer and use it in GitHub Desktop.
Experimental callable rules for CI_Form_validation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php | |
index 0c4f949..0a80888 100644 | |
--- a/system/libraries/Form_validation.php | |
+++ b/system/libraries/Form_validation.php | |
@@ -144,7 +144,7 @@ class CI_Form_validation { | |
* Set Rules | |
* | |
* This function takes an array of field names and validation | |
- * rules as input, any custom error messages, validates the info, | |
+ * rules as input, any custom error messages, validates the info, | |
* and stores it | |
* | |
* @param mixed $field | |
@@ -153,7 +153,7 @@ class CI_Form_validation { | |
* @param array $errors | |
* @return CI_Form_validation | |
*/ | |
- public function set_rules($field, $label = '', $rules = '', $errors = array()) | |
+ public function set_rules($field, $label = '', $rules = array(), $errors = array()) | |
{ | |
// No reason to set rules if we have no POST data | |
// or a validation array has not been specified | |
@@ -187,26 +187,32 @@ class CI_Form_validation { | |
return $this; | |
} | |
- // Convert an array of rules to a string | |
- if (is_array($rules)) | |
- { | |
- $rules = implode('|', $rules); | |
- } | |
- | |
// No fields? Nothing to do... | |
- if ( ! is_string($field) OR ! is_string($rules) OR $field === '') | |
+ if ( ! is_string($field) OR $field === '') | |
{ | |
return $this; | |
} | |
+ elseif ( ! is_array($rules)) | |
+ { | |
+ // BC: Convert pipe-separated rules string to an array | |
+ if (is_string($rules)) | |
+ { | |
+ $rules = explode('|', $rules); | |
+ } | |
+ else | |
+ { | |
+ return $this; | |
+ } | |
+ } | |
// If the field label wasn't passed we use the field name | |
$label = ($label === '') ? $field : $label; | |
// 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 | |
- $indexes = array(); | |
- if (preg_match_all('/\[(.*?)\]/', $field, $matches)) | |
+ if (($is_array = (bool) preg_match_all('/\[(.*?)\]/', $field, $matches)) === TRUE) | |
{ | |
+ $indexes = array(); | |
sscanf($field, '%[^[][', $indexes[0]); | |
for ($i = 0, $c = count($matches[0]); $i < $c; $i++) | |
@@ -219,10 +225,6 @@ class CI_Form_validation { | |
$is_array = TRUE; | |
} | |
- else | |
- { | |
- $is_array = FALSE; | |
- } | |
// Build our master array | |
$this->_field_data[$field] = array( | |
@@ -468,7 +470,7 @@ class CI_Form_validation { | |
continue; | |
} | |
- $this->_execute($row, explode('|', $row['rules']), $this->_field_data[$field]['postdata']); | |
+ $this->_execute($row, $row['rules'], $this->_field_data[$field]['postdata']); | |
} | |
// Did we end up with any errors? | |
@@ -591,19 +593,33 @@ class CI_Form_validation { | |
if ( ! in_array('required', $rules) && ($postdata === NULL OR $postdata === '')) | |
{ | |
// Before we bail out, does the rule contain a callback? | |
- if (preg_match('/(callback_\w+(\[.*?\])?)/', implode(' ', $rules), $match)) | |
+ foreach ($rules as &$rule) | |
{ | |
- $callback = TRUE; | |
- $rules = array(1 => $match[1]); | |
+ if (is_string($rule)) | |
+ { | |
+ if (strncmp($rule, 'callback_', 9) === 0) | |
+ { | |
+ $callback = TRUE; | |
+ $rules = array(1 => $rule); | |
+ break; | |
+ } | |
+ } | |
+ elseif (is_callable($rule)) | |
+ { | |
+ $callback = TRUE; | |
+ $rules = array(1 => $rule); | |
+ break; | |
+ } | |
} | |
- else | |
+ | |
+ if ( ! $callback) | |
{ | |
return; | |
} | |
} | |
// Isset Test. Typically this rule will only apply to checkboxes. | |
- if (($postdata === NULL OR $postdata === '') && $callback === FALSE) | |
+ if (($postdata === NULL OR $postdata === '') && ! $callback) | |
{ | |
if (in_array('isset', $rules, TRUE) OR in_array('required', $rules)) | |
{ | |
@@ -668,39 +684,55 @@ class CI_Form_validation { | |
// somebody messing with the form on the client side, so we'll just consider | |
// it an empty field | |
$postdata = is_array($this->_field_data[$row['field']]['postdata']) | |
- ? NULL | |
- : $this->_field_data[$row['field']]['postdata']; | |
+ ? NULL | |
+ : $this->_field_data[$row['field']]['postdata']; | |
} | |
// Is the rule a callback? | |
- $callback = FALSE; | |
- if (strpos($rule, 'callback_') === 0) | |
+ $callback = $callable = FALSE; | |
+ if (is_string($rule)) | |
{ | |
- $rule = substr($rule, 9); | |
- $callback = TRUE; | |
+ if (strpos($rule, 'callback_') === 0) | |
+ { | |
+ $rule = substr($rule, 9); | |
+ $callback = TRUE; | |
+ } | |
+ } | |
+ elseif (is_callable($rule)) | |
+ { | |
+ $callable = TRUE; | |
} | |
// Strip the parameter (if exists) from the rule | |
// Rules can contain a parameter: max_length[5] | |
$param = FALSE; | |
- if (preg_match('/(.*?)\[(.*)\]/', $rule, $match)) | |
+ if ( ! $callable && preg_match('/(.*?)\[(.*)\]/', $rule, $match)) | |
{ | |
$rule = $match[1]; | |
$param = $match[2]; | |
} | |
// Call the function that corresponds to the rule | |
- if ($callback === TRUE) | |
+ if ($callback OR $callable) | |
{ | |
- if ( ! method_exists($this->CI, $rule)) | |
+ if ($callback) | |
{ | |
- log_message('debug', 'Unable to find callback validation rule: '.$rule); | |
- $result = FALSE; | |
+ if ( ! method_exists($this->CI, $rule)) | |
+ { | |
+ log_message('debug', 'Unable to find callback validation rule: '.$rule); | |
+ $result = FALSE; | |
+ } | |
+ else | |
+ { | |
+ // Run the function and grab the result | |
+ $result = $this->CI->$rule($postdata, $param); | |
+ } | |
} | |
else | |
{ | |
- // Run the function and grab the result | |
- $result = $this->CI->$rule($postdata, $param); | |
+ $result = is_array($rule) | |
+ ? $rule[0]->{$rule[1]}($postdata, $param) | |
+ : $rule($postdata, $param); | |
} | |
// Re-assign the result to the master data array | |
@@ -725,6 +757,7 @@ class CI_Form_validation { | |
// Users can use any native PHP function call that has one param. | |
if (function_exists($rule)) | |
{ | |
+ // Native PHP functions issue warnings if you pass them more parameters than they use | |
$result = ($param !== FALSE) ? $rule($postdata, $param) : $rule($postdata); | |
if ($_in_array === TRUE) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment