CodeIgniter Forums

Full Version: Form Validation callbacks not passing returned value to next rule
You're currently viewing a stripped down version of our content. View the full version with proper formatting.

El Forum

[eluser]september28[/eluser]
Hi There,

i am running CI reactor v 2.0.1 and have created some callback rules for my form validation. They are basically decoding a field that has been encrypted using Codeigniter's encrypt library. In this case I am Encrypting an email address (the string) and salting it with the API Key that the controller is being passed (the controller is accessed through an api call and X-API-KEY header is set to the correct API key).
Here is my rule code:
Code:
$email_params = "{$this->input->post('email')},{$this->rest->key}";
    $em_t = $this->encrypt->decode($this->input->post('email'),$this->rest->key);
    log_message('debug',$email_params);
    log_message('debug',$em_t);
    log_message('debug',$this->_decode_hash_rule('blah',$email_params));
    $this->form_validation->set_rules('email','Email',"required|callback__decode_hash_rule[$email_params]|valid_email");
As you can see, my callback rule is called _decode_hash_rule and takes both the raw post string and the $email_params variable.
The log_message calls are in for debugging purposes and all display the correct values in the log (this first shows the encrypted string and key, the second shows the decoded email and the third shows the decrypted email as returned by the callback function itself).

My callback function is the following:
Code:
/*
     * _decode_hash_rule
     * This is the form validation rule version of the _decode_hash method
     */
    function _decode_hash_rule($str='',$params='')
    {
    list($email_hash, $key) = explode(',', $params);
    if( ! $ret = $this->_decode_hash($email_hash, $key))
    {
        $this->form_validation->set_message('_decode_hash', lang('api_proper_encryption'));
        return FALSE;
    }
    log_message('debug','decode_hash_rule returns: '.$ret);
    return $ret;
    }
    /*
     * _decode_hash(str, params)
     * This is a form validation function that decodes the hashed email.
     * If the hashed string is correctly decoded, it is passed back as an unhashed
     * string, ready for any other validation rules (such as valid_email)#
     * if it fails, an error message is set, and the nothing is returned (string
     * will remained unchanged).
     */
    function _decode_hash($str='', $key='')
    {
        $decoded = $this->encrypt->decode($str, $key);
        if($decoded)
        {
            return $decoded;
        }
    else
    {
        return FALSE;
    }
    }

As you can see I also have a debug log message on the _decode_hash_rule method which also returns the decoded email address ([email protected] - the "Xs" are just there to blur the email)

i also have put a debug log on the valid_email method in the Form_Validation library (system/libraries/Form_Validation.php). This returns the ENCRYPTED string still which prooves that the cascading rules are not functioning properly. Since the encrypted string is not a valid email, I receive the valid email error and so the form doesnt pass validation.

In the Codeigniter userguide it states that the rules will be run right to left and either return booleen true or false, or return the processed value. if the processed value is returned, it will be used in all subsequent rules. In my example it doesn't seem to be happening. Does anyone know why this might be happening? Is this a bug in Codeigniter?

Cheers,

Dan

El Forum

[eluser]LuckyFella73[/eluser]
Hi Dan,

is there a reason why you encode the email address before validating?
Maybe I have overlooked something (you try to achieve) but I think you
could just check if the email (like submitted by the form) is valid and
if the whole validation is completed encode the data before saving in a db.

El Forum

[eluser]september28[/eluser]
Hi there LuckyFella,

The reason is that I am sending data from one server to the other with an api call. I therefore don't want to send the email address unencrypted across the internet. The setup is as follows:

Customer server sends order form to company server which contains order items and customer id and email address. Email address and customer id are encrypted using the api key as a salt.

Company server recieves order and runs validation on post data. Company server first needs to decrypt email and customer id using the api key used to request the url. This all works fine. And as mentioned, my callback function also returns the email address nicely. However the Form_validation library doesn't seem to be passing the decrypted string to the valid_email rule (which is the next rule after the callback), even though I am returning a string from my callback function and not a boolean value.

Hope this makes sense.

El Forum

[eluser]LuckyFella73[/eluser]
I think the form validation rules are mapped directly to the
post values of the defined field-names. If you have to decode
first and then validate, call the "valid_email" method from
within you callback function. I didn't try but that should work.

El Forum

[eluser]september28[/eluser]
Yep, well the way I solved this was to copy the valid_email method contents into my valid_hash callback, however your suggestion is better code, since it avoids code replication. So now the callback rule is called callback__decode_email_hash_rule and it first decrypts and then runs the email validation.

Code:
/**
     * decode_email_hash_rule
     * @param string $str
     * @param string $params
     * @return bool
     * This function wraps decode_hash_rule and _decode_hash to check for a valid Encrypted hash and then valid email if the encrypted hash decrypts correctly
     */
    function _decode_email_hash_rule($str='',$params='')
    {
    $r = $this->_decode_hash_rule($str, $params);
    if($r)
    {
        log_message('debug','decode_email_hash_rule returns: '.$r);
        return $this->form_validation->valid_email($r);
    }
    return FALSE;
    }
    
    /*
     * _decode_hash_rule
     * This is the form validation rule version of the _decode_hash method
     */
    function _decode_hash_rule($str='',$params='')
    {
    list($email_hash, $key) = explode(',', $params);
    if( ! $ret = $this->_decode_hash($email_hash, $key))
    {
        $this->form_validation->set_message('_decode_hash', lang('api_proper_encryption'));
        return FALSE;
    }
    return $ret;
    }
    /*
     * _decode_hash(str, params)
     * This is a form validation function that decodes the hashed email.
     * If the hashed string is correctly decoded, it is passed back as an unhashed
     * string, ready for any other validation rules (such as valid_email)#
     * if it fails, an error message is set, and the nothing is returned (string
     * will remained unchanged).
     */
    function _decode_hash($str='', $key='')
    {
        $decoded = $this->encrypt->decode($str, $key);
        if($decoded)
        {
            return $decoded;
        }
    else
    {
        return FALSE;
    }
    }

Since the codeigniter user guide says that each validation rule will pass the newly processed data to the next rule, I consider this a bug in the CI code.

Dan