summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--system/database/drivers/mysqli/mysqli_driver.php2
-rw-r--r--system/libraries/Form_validation.php101
-rw-r--r--user_guide_src/source/changelog.rst1
-rw-r--r--user_guide_src/source/libraries/form_validation.rst38
4 files changed, 106 insertions, 36 deletions
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index 6ab304901..c5565f629 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -163,7 +163,7 @@ class CI_DB_mysqli_driver extends CI_DB {
*/
protected function _db_set_charset($charset)
{
- return @$this->conn_id->set_charset($charset);
+ return $this->conn_id->set_charset($charset);
}
// --------------------------------------------------------------------
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index 0c4f94914..0a80888d2 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)
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index 423755b89..36ddbc92e 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -345,6 +345,7 @@ Release Date: Not Released
- :doc:`Language <libraries/language>` line keys must now be prefixed with **form_validation_**.
- Added rule **alpha_numeric_spaces**.
- Added support for custom error messages per field rule.
+ - Added support for callable rules when they are passed as an array.
- :doc:`Caching Library <libraries/caching>` changes include:
diff --git a/user_guide_src/source/libraries/form_validation.rst b/user_guide_src/source/libraries/form_validation.rst
index 988d6fa25..e51630905 100644
--- a/user_guide_src/source/libraries/form_validation.rst
+++ b/user_guide_src/source/libraries/form_validation.rst
@@ -474,6 +474,42 @@ then it will be passed as the second argument of your callback method.
boolean TRUE/FALSE it is assumed that the data is your newly processed
form data.
+Callable: Use anything as a rule
+================================
+
+If callback rules aren't good enough for you (for example, because they are
+limited to your controller), don't get disappointed, there's one more way
+to create custom rules: anything that ``is_callable()`` would return TRUE for.
+
+Consider the following example::
+
+ $this->form_validation->set_rules(
+ 'username', 'Username',
+ array(
+ 'required',
+ array($this->users_model, 'valid_username')
+ )
+ );
+
+The above code would use the ``valid_username()`` method from your
+``Users_model`` object.
+
+This is just an example of course, and callbacks aren't limited to models.
+You can use any object/method that accepts the field value as its' first
+parameter. Or if you're running PHP 5.3+, you can also use an anonymous
+function:
+
+ $this->form_validation->set_rules(
+ 'username', 'Username',
+ array(
+ 'required',
+ function($value)
+ {
+ // Check $value and return TRUE/FALSE
+ }
+ )
+ );
+
.. _setting-error-messages:
Setting Error Messages
@@ -491,7 +527,7 @@ If you need to set a custom error message for a particular field on
some particular rule, use the set_rules() method::
$this->form_validation->set_rules('field_name', 'Field Label', 'rule1|rule2|rule3',
- array('rule2' => 'Error Message on rule2 for this field_name')
+ array('rule2' => 'Error Message on rule2 for this field_name')
);
Where rule corresponds to the name of a particular rule, and Error