Search code examples
codeigniter-4

Codeigniter 4 allow user to login using either username or email


Currently I have a login feature and I have only set user can login using username. How do I make it for user to login either using username or email and check with my database if username exist when users login with their username and if email exist when users login with their email? Below is my current code:

Controller

public function login()
    {
        $data = [];
        helper(['form']);
        
        $validation =  \Config\Services::validation();
        
        if($this->request->getMethod() == 'post'){
            //validations
            $rules = [
                'username' => 'required',
                'password' => 'required|validateUser[username, password]'
            ];
            
            $errors = [
                'password' => [
                    'validateUser' => 'Username or Password don\'t match'
                ]
            ];
            
            if(!$this->validate($rules, $errors)){
                $data['validation'] = $this->validator;
            }else{
                $model = new AccountModel();
                
                $user = $model->where('username', $this->request->getVar('username'))
                              ->first();
                              
                $this->setUserSession($user);
                return redirect()->to('/account/profile');
                
            }
            
        }
        
        echo view('templates/header', $data);
        echo view('account/login');
        echo view('templates/footer');
    }

My validation rules

<?php

namespace App\Validation;

use App\Models\AccountModel;

class UserRules
{
    
    public function validateUser(string $str, string $fields, array $data)
    {
        $model = new AccountModel();
        $user = $model->where('username', $data['username'])
                      ->first();
                      
        if(!$user)
            return false;
        
        return password_verify($data['password'], $user['password']);
    }
}

?>

Thanks in advance guys!


Solution

  • First, the username and the email must be unique. So, when the user enters an input either email or username you can check if the user enters email using the following code

    $email = $this->request->getPost('email');
    if(substr_count($email , '@') > 0) // this is an email 
    check for the email if its exists in the database
    else // not an email which means it is username 
    check for the username if its exists in the database
    

    You can find this function substr_count()

    Edit: You can use orWhere function so for example

    $model->where('username' , $username)->orWhere('email',$email)->find()
    

    so this will produce this statement

    select * from tablename where username='' or email =''