How to pass the third parameter to UserIdentity on login authentication

In this wiki I will show how could wo pass the third parameter to UserIdentity on login authenticate. So we can do separate login authentcation from two or more different models from single login form.

In LoginForm Model -

Added a new variable like - usertype. also we will pass it's to UserIdentity same as username & password.

eg.

$this->_identity = new UserIdentity($this->username, $this->password, $this->usertype);
class LoginForm extends CFormModel
{
	public $username;
	public $password;
	public $usertype;
	public $rememberMe;

	private $_identity;
	

	/**
	 * Declares the validation rules.
	 * The rules state that username and password are required,
	 * and password needs to be authenticated.
	 */
	public function rules()
	{
		return array(
			// username and password are required
			array('username, password, usertype', 'required'),
			// rememberMe needs to be a boolean
			array('rememberMe', 'boolean'),
			// password needs to be authenticated
			array('password', 'authenticate'),
		);
	}

	/**
	 * Declares attribute labels.
	 */
	public function attributeLabels()
	{
		return array(
			'rememberMe'=>'Remember me next time',
			'usertype'=>'User Type',
		);
	}

	/**
	 * Authenticates the password.
	 * This is the 'authenticate' validator as declared in rules().
	 */
	public function authenticate($attribute, $params)
	{
		if(!$this->hasErrors())
		{
			$this->_identity = new UserIdentity($this->username, $this->password, $this->usertype);
			if(!$this->_identity->authenticate())
				$this->addError('password','Incorrect username or password.');
		}
	}

	/**
	 * Logs in the user using the given username and password in the model.
	 * @return boolean whether login is successful
	 */
	public function login()
	{
		if($this->_identity===null)
		{
			$this->_identity = new UserIdentity($this->username, $this->password, $this->usertype);
			$this->_identity->authenticate();
		}
		if($this->_identity->errorCode===UserIdentity::ERROR_NONE)
		{
			$duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days
			Yii::app()->user->login($this->_identity,$duration);
			return true;
		}
		else
			return false;
	}
}

In Login View -

Here i'm using two different user type authentication - User & Agency

<?php $form = $this->beginWidget('CActiveForm', array(
                    'id'=>'login-form',
                    'enableClientValidation'=>true,
                    'clientOptions'=>array(
                        'validateOnSubmit'=>true,
                    ),
     )); ?>

<?php echo $form->labelEx($model,'username'); ?>
<?php echo $form->textField($model,'username', array('class'=>'form-control', 'placeholder'=>'Username')); ?>
<?php echo $form->error($model,'username'); ?>

<?php echo $form->labelEx($model,'password'); ?>
<?php echo $form->passwordField($model,'password', array('class'=>'form-control', 'placeholder'=>'Password')); ?>
<?php echo $form->error($model,'password'); ?>

        
<?php echo $form->labelEx($model,'usertype'); ?>
<?php echo $form->dropDownList($model, 'usertype', array('U' => 'User', 'A' => 'Agency'),
              array('empty' => '-- Select User Type --', 'class'=>'form-control')); ?>
<?php echo $form->error($model,'usertype'); ?>
              
<?php echo CHtml::submitButton('Login',	array('class'=>'btn-login')); ?>

<?php $this->endWidget(); ?>

In Controller (actionLogin method) -

public function actionLogin(){
	
	$model = new LoginForm();

	if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form'){
			echo CActiveForm::validate($model);
			Yii::app()->end();
		}

	if (isset($_POST['LoginForm'])){
		
		$model->attributes = $_POST['LoginForm'];
		if ($model->validate(array('username', 'password', 'usertype')) && $model->login())
				$this->redirect(array('site/index'));
	  }	
	$this->render('login', array('model' => $model));
}

In UserIdentity

Need to update UserIdentity.php (In Component directory). Here we will getting third parameter 'usertype' as per we define & pass in LoginForm model.

We will update the CUserIdentity construct method to getting third parameter 'usertype' values. http://www.yiiframework.com/doc/api/1.1/CUserIdentity#__construct-detail

class UserIdentity extends CUserIdentity {
	/**
	 * @var integer id of logged user
	 */
	private $_id;
	private $_first_name;
	public $usertype;
	
	
	//Must need to add
	public function __construct($username, $password, $usertype)
	{
		$this->username = $username;
		$this->password = $password;
		$this->usertype = $usertype;
	}


	/**
	 * Authenticates username and password
	 * @return boolean CUserIdentity::ERROR_NONE if successful authentication
	 */
	public function authenticate() {
		
		$attribute = strpos($this->username, '@') ? 'email' : 'username';
		
		if($this->usertype == 'A'){   //User type 'A' indicate to Agents
		
		   $login = Agent::model()->find(array('condition' => $attribute . '=:loginname', 'params' =>
				array(':loginname' => $this->username)));
		}
		
		else if($this->usertype == 'U'){   //User type 'U' indicate to Normal Users
		
			$login = User::model()->find(array('condition' => $attribute . '=:loginname', 'params' =>
				array(':loginname' => $this->username)));
		}
		
		
		//Login Authentication & Validation
		if ($login === null) {
		         
				$this->errorCode = self::ERROR_USERNAME_INVALID;
			} 
	    
		else if ($login->password!= md5($this->password)) {
		
		 		$this->errorCode = self::ERROR_PASSWORD_INVALID;
			}

		 else {
			$this->_id = $login->id;
			$this->username = $login->email;
			$this->_first_name = $login->first_name;
			
			$this->setState('firstName', $login->first_name);
			$this->setState('userType', $this->usertype); //Store user type for sepration

			$this->errorCode = self::ERROR_NONE;
		}
		return !$this->errorCode;
	}


	/**
	 *
	 * @return integer id of the logged user, null if not set
	 */
	public function getId() {
		return $this->_id;
	}
	
	public function getFirstName() {
		return $this->_first_name;
	}

}

Multi user login facility from single login from. Try this, working great in yii 1.1