4

In Codeigniter:

Here is the callback function that I am using for validation:

public function has_match($password, $username){
    if (0) {
        // user exists
        return true;
    }
    else {
        $this->form_validation->set_message('has_match', 'Invalid Username/password entered ' . $password . ' ' . $username);
        return false;
    }
}

Below are the validation rules:

$this->form_validation->set_rules('username', 'Username', 'required');
$this->form_validation->set_rules('password', 'Password', 'required|callback_has_match[username]');

Can any one please tell me what I am doing wrong here in calling the callback function, as I am unable to get the value of the username field and it keeps showing 'username' (inside the variable $username in callback) instead?

Kamran Ahmed
  • 11,809
  • 23
  • 69
  • 101

3 Answers3

8

Your code is working as expected. You're basically always calling the callback method has_match with the string username as a parameter. I think that you expect that this translates into:

callback_has_match[$username]

Therefore, when you access the has_match() method, you would have access to the value of $username. This is however, not the way callback methods work. The parameter that you set in there is a string, which is hardcoded, exactly like you do when you add a rule for min_length[10] - it's not the value of a PHP variable. An easy fix, which I haven't tested but suspect works is to do:

$this->form_validation->set_rules('password', 'Password', 'required|callback_has_match[' . $username . ']');

However the code above is not clean, and seems bad design in my opinion.

Now that we've found the problem with the code, I know it's outside the scope of the question, but I would like to point it out - I find it's more of a design issue here. Why do you want to check for the username/password pair inside of a callback to the password field?

Remember, you're validating a form, you shouldn't mix it up with model work. The form doesn't care if the provided username/password combo is correct, it should just look at whether both the fields have been provided correctly, and if so, it should do something about it.

I would adapt your code above to:

$this->form_validation->set_rules('username', 'Username', 'required');
$this->form_validation->set_rules('password', 'Password', 'required|callback_has_match[username]');

if ($this->form_validation->run() != FALSE) {
    $validLogin = $this->muser->checkLogin($username, $password);

    if ($validLogin) {
        //Username/password combo exists in DB, save in session or whatever.
    } else {
        //Username/password combo does not exist in DB, show an error.
    }
} else {
    //Code for when form fields have not been provided correctly.
}
Petre Pătraşc
  • 2,203
  • 2
  • 19
  • 17
  • well hmmmm. i think there could be something said for checking the username in a callback first. and THEN checking username / password. think about it from the users perspective. they probably know their username but maybe they forgot the password. so being able to kick back the form with the user name that we know is good - that makes it easier for everyone. – cartalot Oct 11 '13 at 22:53
  • now think about it from the system - if the username is no good - then why should we advance and check the password? AND this is the most important part - if we already know there is a username in our system that they have submitted - then if JUST the password is wrong - we can reassure them - yes we do have a user by that name, but the password you have entered is wrong - and then maybe give them option to redo the password via email, etc. – cartalot Oct 11 '13 at 22:55
  • i tried to edit my comment but stack won't let me -- anyway in first comment meant to say check user name in a callback - form is then validated - then check user & password in separate step like you are suggesting. – cartalot Oct 11 '13 at 23:00
  • Very well explained. I am surely going to adapt my design to as you suggested :) – Kamran Ahmed Oct 12 '13 at 07:07
  • Very good ! and if the $username contains a bracket, the system automatically "escape" it... – sly63 Oct 17 '14 at 05:00
1

Instead of sending parameters with call back you can always get them with post

Here is your call back

public function has_match(){
    if (0) {
        // user exists
        return true;
    }
    else {

        $password   =   $this->input->post('password');
        $username   =   $this->input->post('username');

        $this->form_validation->set_message('has_match', 'Invalid Username/password entered ' . $password . ' ' . $username);
        return false;
    }
}
Muhammad Raheel
  • 19,823
  • 7
  • 67
  • 103
0

// CALLBACKS

public function check_user(){

    $result = FALSE;

    $username=$this->input->post('username');

    $email=$this->input->post('emailad');

    $dbmember=$this->members->get_members();

    foreach ( $dbmember as $key){

        // condition of username and email  
        if($username==$key && $email==$key){

        if($username == $key->UserName && $email == $key->EmailAddress){
              $this->form_validation->set_message('check_user','already existed!
                      Please check username and email agian.');
              return FALSE;
              break;
            }                

        return TRUE;

        }  
    }
sokhy
  • 1
  • 1