[eluser]TheFuzzy0ne[/eluser]
Code:
// If the field isn't required and we just processed a callback we'll move on...
if ( ! in_array('required', $rules, TRUE) AND $result !== FALSE)
{
return;
}
}
else
{
if ( ! method_exists($this, $rule))
{
// If our own wrapper function doesn't exist we see if a native PHP function does.
// Users can use any native PHP function call that has one param.
if (function_exists($rule))
{
$result = $rule($postdata);
if ($_in_array == TRUE)
{
$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
}
else
{
$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
}
}
continue;
}
$result = $this->$rule($postdata, $param);
if ($_in_array == TRUE)
{
$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
}
else
{
$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
}
}
// Did the rule test negatively? If so, grab the error.
if ($result === FALSE)
{
if ( ! isset($this->_error_messages[$rule]))
{
if (FALSE === ($line = $this->CI->lang->line($rule)))
{
$line = 'Unable to access an error message corresponding to your field name.';
}
}
else
{
$line = $this->_error_messages[$rule];
}
// Build the error message
$message = sprintf($line, $this->_translate_fieldname($row['label']), $param);
// Save the error message
$this->_field_data[$row['field']]['error'] = $message;
if ( ! isset($this->_error_array[$row['field']]))
{
$this->_error_array[$row['field']] = $message;
}
return;
}
}
}
}
Now I can define a callback rule using callback_some_rule any my method will look like this:
Code:
function callback_some_rule($str)
{
$this->form_validation->set_message('callback_some_rule', 'Uh-oh!');
// ...
}
You can also define your callback like this if you want to make it prviate (you would still use the same rule name though, no leading underscore necessary):
Code:
function _callback_some_rule($str)
{
$this->form_validation->set_message('_callback_some_rule', 'Uh-oh!');
// ...
}
However I chose to customise the controller constructor, and add a method that denies access to any controller methods starting with "callback_".
./system/application/libraries/MY_Controller.php
Code:
<?php
class MY_Controller extends Controller {
function MY_Controller()
{
parent::Controller();
$this->_validate_controller_method();
}
function _validate_controller_method()
{
if (strncmp($this->uri->rsegment(2), 'callback_', 9) == 0)
{
show_404();
}
}
}
Of course, this will not break any of your old validation methods. It's fully backwards compatible.
Now all my callbacks are safe from external access, and I can see which methods are callbacks for the validation class.
I was contemplating taking it a step further, and prefixing validation methods with vcb instead, just in case anyone wanted a method that started with "callback_" to be accessible externally, but perhaps it's overkill?
If anyone likes this idea, and has any suggestions, please fire away.