Yii, Модуль SRBAC часть 2. Пишем регистрацию

После того как мы подключили и настроили модуль srbac нам необходимо сделать регистрацию пользователей на нашем сайте. Этим сейчас и займемся.

Оговорюсь сразу, что для выполнения этого урока требуется yii версии 1.1.1 и дополнение email.

Почему взята именно эта, а не стабильная версия 1.1.0, потому что в новой версии появился очень интересный виджет «CActiveForm» позволяющий проводить валидацию форм на стороне клиента.

Кстати на счет этого виджета, если кто-то знает, как заставить его проводить валидацию по правилам, как например:

$model->validate('reg');


буду очень признателен.

Закончим это лирическое отступление и перейдем непосредственно к программированию.

Первым делам устанавливаем дополнение email. Как? На странице документации все подробно расписано и думаю, это затруднений не вызовет. Правда у данного модуля есть проблемка с отправлением сообщений на русском языке. Для ее устранения открываем “protected/extensions/email/Email.php” находим функцию mail() и заменяем mb_send_mail на mail. И все отлично работает.

У нас уже есть таблица User и конечно же модель User в папке “protected/models”. Вот как выглядит моя таблица User:

CREATE TABLE IF NOT EXISTS `User` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(100) NOT NULL,
  `username` varchar(100) NOT NULL,
  `password` varchar(32) NOT NULL,
  `createtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `activationKey` varchar(32) NOT NULL,
  `status` varchar(1) NOT NULL,
  PRIMARY KEY (`id`)
)


На этом приготовления закончены, перейдем непосредственно к модулю регистрации.

Для этого создадим модуль “User” из консоли yiic и в DefaultController.php добавим функцию регистрации:

/*
* Регистрация
*
* @param
* @return
*/
public function actionRegistration() {
 
}


После добавим вспомогательные функции для ajax валидации данных и для отправки кода активации на почту.

protected function performAjaxValidation($model) {
       if(isset($_POST['ajax']) && $_POST['ajax']==='user-form') {
           echo CActiveForm::validate($model);
           Yii::app()->end();
       }
   }
 
 
   /*
   * Отправление кода активации
   *
   * @param model $model
   * @return bolean
   */
   protected function activationKey($model) {
       $email = Yii::app()->email;
 
       $email->to = $model->email;
 
       $email->subject = 'Код активации аккаунта для сайта '.Yii::app()->name;
 
       $email->message = 'Код активации аккаунта: <a href="'.Yii::app()->homeUrl.'/user/default/activation/key/'.$model->activationKey.'">'.$model->activationKey.'</a>';
     
       $email->send();
   }


Тут все предельно просто. В первой функции проверяем, откуда пришел запрос и если он ajax то проводим валидацию данных.

Во второй функции создаем экземпляр класса email, устанавливаем значения для необходимых полей и отправляем письмо.

После этого простые рутинные операции, как при создании любой формы. Добавим действие captcha:

function actions() {
        return array('captcha'=>array(
                        'class'     =>'CCaptchaAction',
                        'maxLength' => 6,
                        'minLength' => 3,
                        'foreColor' => 0x667e9a,
                        'testLimit' => 2,)
        );
    }


Для вывода каптчи в форме регистрации и установим минимальную длинну кода на картинке в «3» символа, максимальную в «6», колличество попыток ввода до смены кода «2», что бы пользователь при ошибочном вводе кода видел свою ошибку.

Теперь создадим форму регистрации, для этого в папке «protected.modules/User/views/default» создадим файл “registration.php” и добавим следующий код:

<?php
$this->breadcrumbs=array(
        "Регистрация",
);
?>
 
<h1>Регистрация</h1>
 
<div class="form">
    <?php $form = $this->beginWidget('CActiveForm', array(
            'id'=>'user-form',
            'enableAjaxValidation'=>true,
    )); ?>
 
    <p class="note">Поля со <span class="required">*</span> обязательны.</p>
 
    <?php echo $form->errorSummary($model); ?>
 
    <div class="row">
        <?php echo $form->label($model, 'email', array('class' => 'required')); ?>
        <?php echo $form->textField($model, 'email')?>
        <?php echo $form->error($model,'email'); ?>
    </div>
 
    <div class="row">
        <?php echo $form->label($model, 'username'); ?>
        <?php echo $form->textField($model, 'username' )?>
        <?php echo $form->error($model,'username'); ?>
    </div>
 
    <div class="row">
        <?php echo $form->label($model, 'password'); ?>
        <?php echo $form->passwordField($model, 'password') ?>
        <?php echo $form->error($model,'password'); ?>
    </div>
 
    <div class="row">
        <?php echo $form->label($model, 'password2'); ?>
        <?php echo $form->passwordField($model, 'password2') ?>
        <?php echo $form->error($model,'password2'); ?>
    </div>
 
    <div class="row">
        <?php $this->widget('CCaptcha', array('buttonLabel' => '<br>[новый код]')); ?>
        <?php echo $form->label($model, 'captcha'); ?>
        <?=CHtml::activeTextField($model,'captcha'); ?>
    </div>
 
    <div class="row submit">
        <?=CHtml::submitButton('Зарегистрироваться', array('id' => "submit")); ?>
    </div>
 
    <?php $this->endWidget(); ?>
</div><!-- form -->

Перейдем к доработке модели User. Добавим два параметра:

public $captcha;
public $password2;


Установим имена для аттрибутов:

public function attributeLabels() {
         return array(
             'email'     => 'E-mail адресс:',
             'username'  => 'Имя пользователя:',
             'password'  => 'Пароль:',
             'password2' => 'Пароль еще раз:',
             'captcha'   => 'Введите код с картинки:',
         );
     }


И опишем правила валидации для полей:

/*
    * Правила валидации
    *
    * @param
    * @return
    */
    public function rules() {
        return array(
            array('email, username, password, password2, captcha', 'required', 'on'=>'reg'),
            array('password2', 'compare', 'compareAttribute' => 'password', 'on'=>'reg'),
            array('captcha',  'captcha', 'allowEmpty' => !extension_loaded('gd'), 'on'=>'reg'),
  
            array('email, username', 'required', ),
            array('email',    'match',   'pattern'    => '/^([a-z0-9_\.-]+)@([a-z0-9_\.-]+)\.([a-z\.]{2,6})$/', 'message' => 'Не верный формат e-mail адреса.'),
            array('username', 'match',   'pattern'    => '/^[A-Za-z0-9_-А-Яа-я\s,]+$/u','message'  => 'Логин содержит недопустимые символы.'),
                        
            array('username, email',     'length',  'max' => '100', 'min' => '3',),
            array('password, password2', 'length',  'max' => '40',  'min' => '5',),
        );
    }


Расписывать правила валидации не буду, про это и так много всего написано.

Теперь создадим представление для сообщения об успешной регистрации. Добавим в «protected.modules/User/views/default» файл «registratoinOk.php» со следующим содержимым:

<?php
$this->breadcrumbs=array(
                "Регистрация",
);
?>
 
<h1>Регистрация</h1>
 
<div id="content">
    <h1>Пользователь успешно добавлен!</h1>
</div>


Ну и наконец перейдем непосредственно к коду нашей регистрации:

/*
    * Регистрация
    *
    * @param
    * @return
    */
    public function actionRegistration() {
        if (Yii::app()->user->isGuest) {
  
            $user = new User;
  
            /*
            * Ajax валидация
            */
            $this->performAjaxValidation($user);
 
            if(empty($_POST['User'])) {
                /*
                * Если форма не отправленна, то выводим форму
                */
                $this->render('registration', array('model' => $user));
 
            } else {
                /*
                * Форма получена
                */
                $user->attributes = $_POST['User'];
 
                /*
                * Валидация данных
                */
                if($user->validate('reg')) {
                    /*
                    * Если проверка пройдена, проверяем на уникальность имя
                    * пользователя и e-mail
                    */
                    if($user->model()->count("email = :email",
                        array(':email' => $user->email))) {
 
                        $user->addError('email', 'E-mail уже занят');
                        $this->render("registration", array('model' => $user));
 
                    } else if($user->model()->count("username = :username",
                        array(':username' => $user->username))) {
 
                        $user->addError('username', 'Имя пользователя уже занято');
                        $this->render("registration", array('model' => $user));
 
                    } else {
                        /*
                        * Если проверки пройдены шифруем пароль, генерируем код
                        * активации аккаунта, а также устанавливаем время регистрации
                        * и роль по умолчанию для пользователя
                        */
                        $user->password      = md5(md5($user->password));
                        $user->activationKey = substr(md5(uniqid(rand(), true)), 0, rand(10, 15));
                        $user->status        = '0';
 
                        /*
                        * Проверяем если добавление пользователя прошло успешно
                        * устанавливаем ему права.
                        */
                        if($user->save()) {
                            $role = new AuthAssignment();
                            $role->itemname = 'User';
                            $role->userid   = $user->id;
 
                            if($role->save()) {
                                /*
                                * Если роль успешно добавилась, выводим сообщение
                                * об успешной регистрации и отправляем код активации аккаунта
                                */
                                $this->render("registrationOk");
 
                                $this->activationKey($user);
 
                            } else {
                                throw new CHttpException(403, 'Ошибка добавления в базу данных.');
                            }
                        } else {
                            throw new CHttpException(403, 'Ошибка добавления в базу данных.');
                        }
                    }
                } else {
                    /*
                    * Не прошел валидацию
                    */
                    $this->render('registration', array('model' => $user));
                }
            }
        } else {
            /*
            * Если пользователь залогинен редиректим обратно
            */
            $this->redirect(Yii::app()->user->returnUrl);
        }
    }

Я думаю комментариев в коде достаточно, что бы просто его понять. Если возникнут вопросы пишите в комментариях.
Теги:
SRBAC
Добавлено: 02 Марта 2015 19:27:15 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...