Yii 1.1: Login Form With email or Whatever

2 followers

Here is my solution to login with email or anything else This update works with database mysql You must generate the user model with GII

My login form look like this

<?php
/* @var $this SiteController */
/* @var $model LoginForm */
/* @var $form CActiveForm  */
 
$this->pageTitle=Yii::app()->name . ' - Login';
$this->breadcrumbs=array(
    'Login',
);
?>
 
<h1>Login</h1>
 
<p>Please fill out the following form with your login credentials:</p>
 
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'login-form',
    'enableClientValidation'=>true,
    'clientOptions'=>array(
        'validateOnSubmit'=>true,
    ),
)); ?>
 
    <p class="note">Fields with <span class="required">*</span> are required.</p>
 
    <div class="row">
        <?php echo $form->labelEx($model,'email'); ?>
        <?php echo $form->textField($model,'email'); ?>
        <?php echo $form->error($model,'email'); ?>
    </div>
 
    <div class="row">
        <?php echo $form->labelEx($model,'password'); ?>
        <?php echo $form->passwordField($model,'password'); ?>
        <?php echo $form->error($model,'password'); ?>
        <p class="hint">
            Hint: You may login with <kbd>demo</kbd>/<kbd>demo</kbd> or <kbd>admin</kbd>/<kbd>admin</kbd>.
        </p>
    </div>
 
    <div class="row rememberMe">
        <?php echo $form->checkBox($model,'rememberMe'); ?>
        <?php echo $form->label($model,'rememberMe'); ?>
        <?php echo $form->error($model,'rememberMe'); ?>
    </div>
 
    <div class="row buttons">
        <?php echo CHtml::submitButton('Login'); ?>
    </div>
 
<?php $this->endWidget(); ?>
</div><!-- form -->

In SiteController.php no more changes

/**
     * Displays the login page
     */
    public function actionLogin()
    {
        if (!defined('CRYPT_BLOWFISH')||!CRYPT_BLOWFISH)
            throw new CHttpException(500,"This application requires that PHP was compiled with Blowfish support for crypt().");
 
        $model=new LoginForm;
 
        // if it is ajax validation request
        if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
        {
            echo CActiveForm::validate($model);
            Yii::app()->end();
        }
 
        // collect user input data
        if(isset($_POST['LoginForm']))
        {
            $model->attributes=$_POST['LoginForm'];
            // validate user input and redirect to the previous page if valid
            if($model->validate() && $model->login())
                $this->redirect(Yii::app()->user->returnUrl);
        }
        // display the login form
        $this->render('login',array('model'=>$model));
    }

The LoginForm in models directory

<?php
 
/**
 * LoginForm class.
 * LoginForm is the data structure for keeping
 * user login form data. It is used by the 'login' action of 'SiteController'.
 */
class LoginForm extends CFormModel
{
    public $username;
    public $email;
    public $password;
    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('email, password', 'required'),
            array('email', 'email'),
            // 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',
        );
    }
 
    /**
     * 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->email);
            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->email);
            $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;
    }
}

And finally the UserIdentity in components directory

<?php
 
/**
 * UserIdentity represents the data needed to identity a user.
 * It contains the authentication method that checks if the provided
 * data can identity the user.
 */
class UserIdentity extends CUserIdentity
{
    /**
     * @var string email
     */
    public $email;
    /**
     * @var int id
     */
    private $_id;
 
    const ERROR_EMAIL_INVALID=1;
 
    public function __construct($username, $password, $email)
    {
        parent::__construct($username, $password);
        $this->email=$email;
    }
 
 
    /**
     * Authenticates a user.
     * The example implementation makes sure if the email and password
     * are both 'demo'.
     * In practical applications, this should be changed to authenticate
     * against some persistent user identity storage (e.g. database).
     * @return boolean whether authentication succeeds.
     */
    public function authenticate()
    {
        $model=User::model()->findByAttributes(array('email'=>$this->email));
        if($model===null)
            $this->errorCode=self::ERROR_EMAIL_INVALID;
        elseif(!crypt($this->password, $model->password))
            $this->errorCode=self::ERROR_PASSWORD_INVALID;
        else
            $this->_id=$model->id;
            $this->username=$model->username;
            $this->errorCode=self::ERROR_NONE;
        return !$this->errorCode;
    }
 
    /**
     * @return integer the ID of the user record
     */
    public function getId()
    {
        return $this->_id;
    }
}

Total 1 comment

#17827 report it
andrzej1_1 at 2014/07/26 03:28am
Too complicated

It can be done simpler:

public function authenticate()
{
   //$user=User::model()->find('LOWER(username)=?',array(strtolower($this->username))); comment this line
+  $user=User::model()->findByAttributes(array('email'=>$this->username));
+   if($user===null) { 
+      $user=User::model()->find('LOWER(username)=?',array(strtolower($this->username))); 
+   }
   if($user===null)
...

Leave a comment

Please to leave your comment.

Write new article