Welcome Guest, Not a member yet? Register   Sign In
Calling CI validation from within a callback
#1

[eluser]Pete Smith[/eluser]
Hey folks,

So I needed to do some conditional validation. Basically I give users the option to be invoiced or pay by credit card. So if they pick the Invoice radio button, they're golden, but if they want to pay by credit card, they need to enter Name on Card, Card Number, etc.

So I figured I could do callback functions for card name, card number etc and check the status of the radio button. If it's set to Invoice, return TRUE. If it's set to credit card, then I need to validate.

So I'm wondering if there's any way to call CI's Validation routines from inside a callback, so I get CI's robust validation tools, rather than having to write my own.

Any ideas how I might go about this?
#2

[eluser]Grahack[/eluser]
Something that I find a bit hidden in the docs is that you can pass additional(s?) parameter(s?) to your validating functions.
Look at the min_length() and matches() functions in system/libraries/Validation.php, they have a second parameter. You can send a value, or even the name of an item in your form.
What you could easily do is to code something like
Code:
<?php
// ...
$rules['name_on_card'] = "callback__check_name_on_card[invoice_html_name]";
$rules['card_number'] = "callback__check_card_number[invoice_html_name]";
// ...
function _check_name_on_card( $str, $invoice )
{
    if ( $invoice == 'checked' ) return true;
    // here you will check the name
}
// ...
Note: extending the Validation class is a very wise thing to do, instead of putting the callback in the controller.
#3

[eluser]Pete Smith[/eluser]
Thanks for the reply!

I've gotten that far... I mean, what I have now is very simple...it just checks to see if the field is blank. But your code does it in a much more CI like way. Here's what I'm doing now:

Code:
function _ccdata($str)
{
    if ($_POST['invoice'] == '1') {
        return TRUE;
    }
    else
    {
        if ($str == '')
        {
            $this->validation->set_message('_ccdata', 'The %s field cannot be blank');
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }

}

But this isn't very robust...I'd like to be sure the cc number is numeric, for instance. So I was thinking if there was a way to call CI validate here instead of using, for example, ($str == '')

Maybe if I set up a completely new set of validation rules inside this callback function? Or maybe I'm worrying too much, since the store's credit card processor will flag problems here itself when the system tries to authorize the card.

Quote:Note: extending the Validation class is a very wise thing to do, instead of putting the callback in the controller.

Can you elaborate on this a little? What are the drawbacks of having the callback in the controller? Thanks for any advice you can offer.
#4

[eluser]Grahack[/eluser]
[quote author="Pete Smith" date="1183842807"]Here's what I'm doing now:
Code:
function _ccdata($str)
{
    if ($_POST['invoice'] == '1') {
        return TRUE;
    }
    else
    {
        if ($str == '')
        {
            $this->validation->set_message('_ccdata', 'The %s field cannot be blank');
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }

}

But this isn't very robust...
I'd like to be sure the cc number is numeric, for instance. So I was thinking if there was a way to call CI validate here instead of using, for example, ($str == '')
[/quote]
Why isn't it "robust" ?
For the call of CI's validation, I have an idea, see below after the 'extension' explanation.

Quote:Maybe if I set up a completely new set of validation rules inside this callback function? Or maybe I'm worrying too much, since the store's credit card processor will flag problems here itself when the system tries to authorize the card.
Don't know about your processes, I guess it's better to notice the user as early as possible.
Quote:
Quote:Note: extending the Validation class is a very wise thing to do, instead of putting the callback in the controller.

Can you elaborate on this a little? What are the drawbacks of having the callback in the controller? Thanks for any advice you can offer.
I guess you don't want to have duplicate code if ever you need to do the same validation in another controller.
Moreover, this trick allows you to omit the 'set_message' function, just add a line with the relevant key (function name) in a lang file, that you will load in the constructor.

I don't know if this is explained somewhere else. It's quite basic but very handy for the validation custom processes.
It goes like this:
create a MY_Validation.php file in system/application/libraries folder, with
Code:
<?php if (!defined('BASEPATH')) exit('No direct script access permitted.');

class MY_Validation extends CI_Validation {
    
    function My_Validation()
    {
        parent::CI_Validation();
        // here you could load your lang file
    }

    // put your new functions here
}
You'll have new validation functions as if they were in the base CI Validation.php file.

Now I think (not sure, but you'll test for me), that you can call is_numeric() or any validation function with $this->function_name() since your class extends the base valisation one.
$this->function_name() will replace the set_message() + return BOOL thing.
#5

[eluser]Pete Smith[/eluser]
Ah, very interesting stuff!!

I'd read about extending classes but figured it was a very advanced part of CI and didn't really pay as much attention as I should have. But what you'd illustrated seems like something I could do. Thanks, and I'll report back with what I come up with!




Theme © iAndrew 2016 - Forum software by © MyBB