После того как мы подключили и настроили модуль 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);
}
}
Я думаю комментариев в коде достаточно, что бы просто его понять. Если возникнут вопросы пишите в комментариях.