|
[eluser]vadivelan[/eluser]
Overview:
CI is not dealing with user submitted array values properly.
Impacts:
* You cannot validate listbox (select with multiple enabled), checkbox groups and reselect the user selected values using set_select, set_checkbox for multiple values
* You cannot use trim, htmlspecialchars or any other native php function in rules
* When you enable XSS_Clean in config.php error will pop-up when user select multiple values in list box or check checkbox groups ( ie: checking multiple checkboxes for hobbies in html form )
* You cannot use any other validation rules that CI provides like numeric, integer, xss_clean
What this post address:
This post address the following:
* Allowing to use trim, required, htmlspecialchars or any other native php function call in the rules.
* Allowing to use set_select, set_checkbox for listboxes and checkbox groups, checkboxgroupname_error, listboxname_error
Note:
Still you cannot use CI's validation rules like integer, numeric, xss_clean for arrays. But I don't think these validation will be needed for listboxes and checkbox groups as you are not going to store these values in db / re-display in html. Mostly, you will make use of the values from db / array to populate, validate against user submitted values.
But if you still need to validate for any purpose, you can call those functions in a loop for all the user selected values in a listbox / checkbox.
Solution:
Enabling CI's - Validation library to support list box and check box group is involve replacing the system's Validation.php with our version. To enable this copy system/library/validation.php to application/library/ and do the necessary modification listed below.
This file contains the following modifications:
1. set_select method has been modified to support arrays: (line 617 in original validation.php )
Code: function set_select($field = '', $value = '')
{
if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
{
return '';
}
if(is_array($_POST[$field])) {
if(in_array($value,$_POST[$field])) {
return ' selected="selected"';
}
} elseif ($_POST[$field] == $value) {
return ' selected="selected"';
}
}
2. set_checkbox has been modified to support arrays: (line 669 in original validation.php )
Code: function set_checkbox($field = '', $value = '')
{
if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
{
return '';
}
if(is_array($_POST[$field])) {
if(in_array($value,$_POST[$field])) {
return ' checked="checked"';
}
} elseif ($_POST[$field] == $value) {
return ' checked="checked"';
}
}
3. Prep_for_form function has been updated: (line 694 in original validation.php )
Code: function prep_for_form($data = '')
{
if (is_array($data))
{
foreach ($data as $key => $val)
{
$data[$key] = $this->prep_for_form($val);
}
}
if ($this->_safe_form_data == FALSE OR $data == '')
{
return $data;
}
if(is_array($data)) {
return $data;
} else {
return str_replace(array("'", '"', '<', '>'), array("'", """, '<', '>'), stripslashes($data));
}
}
4. Method php_func_caller has been added. This enables setting rules like trim, htmlspecial chars and other native php function calls that take single parameter and return the same.
Code: /**
* native php function caller
*
* This function calls native php functions for each values submitted from the form
*
* @access public
* @param string
* @return string
* @author r.vadivelan / hivelan [.at.] gmail [.dot.] com
*/
function php_func_caller($rule, $data = '')
{
if (is_array($data))
{
foreach ($data as $key => $val)
{
$data[$key] = $this->php_func_caller($rule,$val);
}
}
if ($data == '')
{
return $data;
}
if(is_array($data)) {
return $data;
} else {
return $rule($data);
}
}
5. Call the php_func_caller when processing rules ( Line no 302 in original validation.php )
Code: if (function_exists($rule))
{
$_POST[$field] = $this->php_func_caller($rule,$_POST[$field]);
$this->$field = $_POST[$field];
}
How to test
* Create a html file containing a select box with multiple enabled, and a checkbox group like hobbies. Make use of set_select, set_checkbox, error_string, checkboxgroupname_error, listboxname_error so that we can verify everything work properly.
* Create a controller, initialize validation libarary, set the rules and fields. Make sure you set trim, required and any other native php functions as rules. Rules like xss_clean, interger ( those given by CI ) will not work ( as CI's validation function's don't support arrays).
Now it would be possible to validate listbox and checkboxes without any problem.
Summary:
Even though I have explained in detail, the entire process is very simple:
1. Just copy system/library/Validation.php to application/library and do the modifications.
2. Validate the listbox and checkbox group as you will normally do for other fields.
Hope this will be useful to you. Please let me know your comments.
|