В прошлой статье я описал как сделать авторизацию через БД в Yii Framework: Yii Framework, авторизация через БД. Теперь можем перейти к добавлению регистрации на сайт.

Yii 1, добавляем регистрацию на сайте

Начнем с модели User. При регистрации нового пользователя ему помимо e-mail и имени необходимо будет ввести пароль и подтвердить его, для этого необходимо в модель добавить свойство password2, в методе rules() задать правило валидации и добавить метку для поля password2 в метод attributeLabels():

<?php

class User extends CActiveRecord
{

    //...

    /**
     * Подтверждение пароля
     *
     * @var string
     */
    public $password2 = '';

    //...

    public function rules()
    {
        return array(

            //...

            array('password2', 'compare', 'compareAttribute' => 'password', 'on' => 'signUp'),
            array('password2', 'required', 'on' => 'signUp'),
            //...
        );
    }

    public function attributeLabels()
    {
        return array(
            //...
            'password2' => 'Repeat password',
         );
    }
    //...
}

Так же при сохранении пользователя необходимо задать дату регистрации, роль и статус автоматически, для этого добавим методы beforeValidate() и beforeSave(), которые и будут этим заниматься:

<?php

class User extends CActiveRecord
{

    //...

    public function beforeValidate()
    {

        if ($this->isNewRecord) {
           $this->date = time();
           $this->status = self::DEFAULT_STATUS;
           $this->role = self::DEFAULT_ROLE;
       }

       return parent::beforeValidate();
    }

    public function beforeSave()
    {

        if ($this->isNewRecord) {
            $this->password = md5($this->password);
        }

        return parent::beforeSave();
    }

}

Теперь добавим действие для регистрации в контроллер SiteController (/protected/controllers/SiteController.php):

<?php

class SiteController extends Controller
{
    //...

    public function actionSignUp()
    {

        if (!Yii::app()->user->isGuest)
            throw new CHttpException(404, 'Error 404');

        $model = new User('signUp');

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

        if(isset($_POST['User'])) {
            $model->attributes = $_POST['User'];

            if($model->save()) {
                $login = new UserIdentity($model->email, $model->password2);
                if($login->authenticate() == '') {
                    Yii::app()->user->login($login, 0);

                    //Здесь можно отправить письмо пользователю о успешной регистрации

                    Yii::app()->user->setFlash('signUp', 'Registration successful');
                    $this->redirect(array('site/index'));
                }

            }

        }

        $this->render('signUp', array('model' => $model));
    }
}

Рассмотрим действие регистрации (actionSignUp) немного подробнее. Для начала проверяем гость ли это, чтобы авторизированным пользователям не была доступна данная страница (это можно решить и с помощью RBAC). Далее проверяем данные с формы, если все хорошо, то сохраняем данные пользователя, авторизируем его, добавляем сообщение об успешной регистрации и перенаправляем пользователя на главную страницу.

Теперь необходимо добавить представление регистрации с формой /protected/views/site/signUp.php:

<?php

$this->pageTitle=Yii::app()->name . ' - Sign Up';
$this->breadcrumbs=array(
    'Sign Up',
);
?>

<h1>Sign Up</h1>

<p>Please fill out the following form with your registration data:</p>

<div class="form">

<?php $form = $this->beginWidget('CActiveForm', array(
    'id' => 'registartion-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, 'name'); ?>
        <?php echo $form->textField($model, 'name'); ?>
        <?php echo $form->error($model, 'name'); ?>
    </div>

    <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'); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($model, 'password2'); ?>
        <?php echo $form->passwordField($model, 'password2'); ?>
        <?php echo $form->error($model, 'password2'); ?>
    </div>

    <div class="row buttons">
        <?php echo CHtml::submitButton('Sign up'); ?>
    </div>

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

</div>

Далее добавляем вывод сообщения об успешной регистрации на главную (/protected/views/site/index.php):

...

<h1>Welcome to <i><?php echo CHtml::encode(Yii::app()->name); ?></i></h1>

<?php if(Yii::app()->user->hasFlash('signUp')) { ?>

    <div class="flash-success">
        <?php echo Yii::app()->user->getFlash('signUp'); ?>
    </div>

<?php } ?>

...

И в меню добавить пункт "Регистрация", для этого открываем файл /protected/views/layouts/main.php и правим виджет CMenu:

...

<div id="mainmenu">

    <?php $this->widget('zii.widgets.CMenu',array(
        'items'=>array(
            array('label'=>'Home', 'url'=>array('/site/index')),
            array('label'=>'About', 'url'=>array('/site/page', 'view'=>'about')),
            array('label'=>'Contact', 'url'=>array('/site/contact')),
            array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest),
            array('label'=>'Sign up', 'url'=>array('/site/signUp'), 'visible'=>Yii::app()->user->isGuest),
            array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest)
        ),
    )); 
    ?>

</div>
...

Регистрация готова, можем тестировать. После того как мы убедились, что все работает, можем перейти к следующему этапу, сброс пароля. Список статей по теме: Yii Framework, авторизация, регистрация и восстановление пароля через БД.