====== Шаг7. Регистрация пользователей ======
===== План действий =====
* Мы создадим контроллер **ProfileController**, который будет содержать действия **register** для самостоятельной регистрации покупателей и **display** для просмотра и редактирования своего профайла.
* Для хранение данных покупателей мы будем использвать уже готовый класса User и прочую инфраструктуру вокруг него.
* Мы поправим шаблон page.html для отображения данных уже залогиненного пользователя и форму для аутентфикации, если пользователь еще не определен.
Большинство операций вам уже должны быть знакомы, поэтому здесь будет минимальное количество комментарий.
===== Регистрация пользователей =====
==== Контроллер ProfileController ====
Создадим класс ProfileController и добавим в него действие register.
Файл shop/src/controller/ProfileController.class.php:
useForm('register_form');
$this->setViewFormDatasource($this->request);
if($this->request->hasPost())
{
$this->_validatePasswordField();
$user = new User();
$user->setLogin($login = $this->request->get('login'));
$user->setEmail($this->request->get('email'));
$user->setName($this->request->get('name'));
$user->setPassword($password = $this->request->get('password'));
$user->setAddress($this->request->get('address'));
$user->setIsAdmin(false);
if($user->trySave($this->error_list) && $this->error_list->isValid())
{
$this->toolkit->getUser()->login($login, $password);
$this->toolkit->getSession()->set('user_id', $user->getId());
$this->flashMessage('Thank you for your registration!');
$this->toolkit->redirect('/');
}
}
}
function _validatePasswordField()
{
$this->validator->addRequiredRule('password');
$this->validator->addRequiredRule('repeat_password');
lmb_require('limb/validation/src/rule/lmbMatchRule.class.php');
$this->validator->addRule(new lmbMatchRule('password', 'repeat_password'));
$this->validator->validate($this->request);
}
}
?>
После регистрации пользователь уже считается прошедшим процедуру аутентификации, и мы перебрасываем его на главную страницу при помощи метода redirect(), а также выводим ему сообщение об успешной регистрации при помощи метода flashMessage().
Код должен быть вам знаком по контроллерам LoginController и AdminUserController.
Обратите внимание на проверку
if($user->trySave($this->error_list) && $this->error_list->isValid())
{
[...]
}
Мы должны обязательно проверить, нет ли ошибок в списке ошибок, так как процесс валидации данных разбит на 2 составляющие - одна из которых производится в контроллере в методе _validatePasswordField(), а вторая - в классе User.
Аналогом метода $error_list->isValid() может выступат просто $error_list->isEmpty().
==== Шаблон profile/register.html ====
Теперь можно будет создать шаблон для действия register.
Файл shop/template/profile/register.html:
Здесь мы использовали одну интересную особенность WACT-тегов для форм. Они позволяют указать атрибутом **errorclass** название CSS-класса, который будет применен к ним, если поля содержат ошибки валидации. Мы решили назвать этот класс error.
==== Предварительные результаты ====
Попробуйте зайти на страницу /profile/register. Наша форма регистрации c ошибками валидации будет выглядеть следующим образом:
{{{limb3_2007_2:ru:tutorials:shop:register_form.png|}}}
===== Изменения в шаблоне page.html =====
Теперь можно внести в paget.html изменения, связанные с отображением данных текущего пользователя. Данные пользователя нам уже доступны в шаблоне в виде переменной user корневого контейнера данных (мы это реализовали в AccessFilter).
Изменения в файле shop/template/page.html:
[..]
[...]
Мы решили отображать форму для аутентификации в левой части страницы, если пользователь не залогинен. Плюс добавился пункт навигации Your Orders, к реализации которого мы скоро также приступим.
===== Редактирование своего профайла =====
Пользователь должен иметь возможность сменить свой пароль, а также поменять свои контактные данные (например, email) при необходимости. Для этого мы реализуем действие display, которое будет в себя включать весь нужный функционал.
Начнем, пожалуй, с шаблона:
==== Шаблон profile/display.html ====
Файл shop/template/profile/display.html:
This is your profile page. You can change some of your profile fields as well as your password
Profile
Password change form
Шаблон содержит 2 формы:
* одна - для изменения своих данных, таких как имя и email, а также адрес доставки.
* вторая - для смены своего текущего пароля.
Теперь мы покажем, как можно обрабатывать 2 формы при помощи одного действия в контроллере.
==== Изменения в ProfileController ====
setViewFormDatasource($this->toolkit->getUser(), 'profile_form');
if($this->request->hasAttribute('change_password'))
$this->_changeUserPassword();
if($this->request->hasAttribute('edit'))
$this->_updateUserProfile();
}
protected function _changeUserPassword()
{
$this->useForm('change_password_form');
$this->_validateChangePasswordForm();
if($this->error_list->isValid())
{
$user = $this->toolkit->getUser();
$user->setPassword($this->request->get('password'));
$user->save();
$this->flashMessage('Your password was changed');
$this->toolkit->redirect();
}
}
protected function _updateUserProfile()
{
$this->useForm('profile_form');
$this->setViewFormDatasource($this->toolkit->getUser());
$user = $this->toolkit->getUser();
$user->setEmail($this->request->get('email'));
$user->setName($this->request->get('name'));
$user->setAddress($this->request->get('address'));
if($user->trySave($this->error_list))
{
$this->flashMessage('Your profile was changed');
$this->toolkit->redirect();
}
}
protected function _validateChangePasswordForm()
{
$this->validator->addRequiredRule('old_password');
$this->_validatePasswordField();
$user = $this->toolkit->getUser();
if($old_password = $this->request->get('old_password'))
{
$hashed_password = User :: cryptPassword($old_password);
if($user->getHashedPassword() != $hashed_password)
$this->error_list->addError('Wrong old password', array('old_password'));
}
}
}
?>
Выбор той или иной функции по обработке формы по смене пароля или же по обновлению данных пользователя осуществляется очень просто - исходя из того, какая переменная пришла в request-е.
Мы также сразу передаем текущего пользователя в форму в шаблоне, так как желаем, чтобы эти данные всегда отображались в полях формы все зависимости от того, какая форма была до этого отправлена. Примем мы использовали только метод lmbController :: setViewFormDatasource($datasource, $form_id):
$this->setViewFormDatasource($this->toolkit->getUser(), 'profile_form');
Это позволит не выводить ошибки валидации сразу рядом с двумя формами, если пользователь неправильно ввел информацию в форму по смене пароля.
===== Предварительные результаты =====
Вот как должна выглядеть страница /profile:
{{{limb3_2007_2:ru:tutorials:shop:profile.png|}}}
===== Далее =====
Теперь можно приступать к интересной части: оформлению заказа и сохранению его в базе данных. Этот функционал позволит нам познакомиться к тем, как в пакете ACTIVE_RECORD реализована поддержка отношений между объктами, таких как один-ко-многим, много-ко-многим и один-к-одному.
Итак, следующий шаг: [[step8|Шаг8. Отправка заказа]].