Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Codeigniter Form Validation Callback checking multiple fields

I have this controller set up for a login:

<?php
class Login extends Controller {

    function __construct() {
        parent::Controller();
        $this->form_validation->set_error_delimiters('', '');
        $this->output->enable_profiler(TRUE);
    }

    function index(){

        redirect('/login/terminal');

    }

    function terminal() {
    // terminal login

        $this->form_validation->set_rules(array('username','password'), 'Username', 'callback_terminal_login_check[$username,$password]');
        if ($this->form_validation->run() == FALSE) {
            $this->load->view('login_header');
            $this->load->view('login_terminal');
            $data['version'] = $this->master->GetVersion();
            $this->load->view('login_footer', $data);
        } else {
            redirect('/terminal');
        }

    }

    function terminal_login_check($username,$password) {
    // callback function to perform terminal login  

        if ($this->authentication->DoTerminalAuthentication($username,$password)) {
            echo $username;
            return TRUE;
        } else {
            $this->form_validation->set_message('terminal_login_check', 'Invalid');
            return FALSE;
        }


    }

}

What I am looking at is the line that does the form validation callback >> $this->form_validation->set_rules(array('username','password'), 'Username', 'callback_terminal_login_check[$username,$password]');

I know this is not right. Basically what I want to do is check the username and password against the Authentication->DoTerminalAuthentication model to process the user's login. I want to pass the $username and $password form fields. Here is my form view if it helps:

<div id="title">Terminal Login</div>
<?php 
    if (validation_errors()) {
        echo '<div id="error">' . validation_errors() . '</div>';
    }
?>

<?=form_open('login/terminal');?>
<?=form_label('Username', 'username')?><br />
<?=form_input(array('id'=>'username','name'=>'username','value'=>set_value('username')))?><br />
<?=form_label('Password', 'password')?><br />
<?=form_password(array('id'=>'password','name'=>'password'))?><br />
<?=form_submit(array('name'=>'passwordsubmit','value'=>'Login >>'))?><br />
<?=form_close();?>
like image 592
muncherelli Avatar asked Aug 20 '10 14:08

muncherelli


3 Answers

Use this in your controller to set your validation rules.

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

And a callback something like this. I'd use a model if you are comparing your post data to a database.

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

  // LOAD MODEL HERE

  if ($this->authentication->DoTerminalAuthentication($username, $password)) 
  {
    echo $username;
    return TRUE;
  } 
  else 
  {
    $this->form_validation->set_message('terminal_login_check', 'Invalid');
    return FALSE;
  }
}

Edit 2013-07-09: Added required field to password validation rule so you don't have to hit the DB if someone doesn't add a password.

like image 55
Nick Pyett Avatar answered Oct 19 '22 12:10

Nick Pyett


As I understand it, form validation works on a field by field basis. To achieve what you want, I would attach the callback to one of the fields (probably the password field would be best) and then access the other form field data using the global POST array. This way you don't need to pass anything to the callback function as parameters.

like image 45
musoNic80 Avatar answered Oct 19 '22 13:10

musoNic80


I prefer to use form validation for simple input validation like checking for empty fields, invalid email addresses, too short passwords etc. I tend not to use form validation for more complex logic like authentication. I'd put the authentication check in the action method rather than in a validation callback function. It would get past your particular problem by side-stepping it.

function terminal() 
{
    $this->form_validation->set_rules('username', 'Username', 'required');
    $this->form_validation->set_rules('password', 'password', 'required');   

    if ($this->form_validation->run()) 
    {
        $username = $this->input->post('username');
        $password = $this->input->post('password');

        if ($this->authentication->DoTerminalAuthentication($username, $password))
        {
            // Handle successful login
        }
        else
        {
            // Authentication failed. Alert the view.
            $this->load->view('terminal', array('login_failed' => true));
        }
    } 
    else 
    {
        $this->load->view('terminal', array('login_failed' => false));
    }
}

And then in the view you can place this below your login form

<?php if ($login_failed) : ?>
    <span id="login-failed-message">Login failed</span>
<?php endif; ?>
like image 2
Stephen Curran Avatar answered Oct 19 '22 11:10

Stephen Curran