====== Шаг7. Регистрация пользователей ====== ===== План действий ===== * Мы создадим контроллер **ProfileController**, который будет содержать действия **register** для самостоятельной регистрации покупателей и **display** для просмотра и редактирования своего профайла. * Для хранение данных покупателей мы будем использвать уже готовый класса User и прочую инфраструктуру вокруг него. * Мы поправим шаблон page.html для отображения данных уже залогиненного пользователя и форму для аутентфикации, если пользователь еще не определен. Большинство операций вам уже должны быть знакомы, поэтому здесь будет минимальное количество комментарий. ===== Регистрация пользователей ===== ==== Контроллер ProfileController ==== Создадим класс ProfileController и добавим в него действие register. Файл shop/src/controller/ProfileController.class.php: useForm('register_form'); $this->setFormDatasource($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_4: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 ==== setFormDatasource($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->setFormDatasource($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 :: setFormDatasource($datasource, $form_id): $this->setFormDatasource($this->toolkit->getUser(), 'profile_form'); Это позволит не выводить ошибки валидации сразу рядом с двумя формами, если пользователь неправильно ввел информацию в форму по смене пароля. ===== Предварительные результаты ===== Вот как должна выглядеть страница /profile: {{{limb3_2007_4:ru:tutorials:shop:profile.png|}}} ===== Далее ===== Теперь можно приступать к интересной части: оформлению заказа и сохранению его в базе данных. Этот функционал позволит нам познакомиться к тем, как в пакете ACTIVE_RECORD реализована поддержка отношений между объктами, таких как один-ко-многим, много-ко-многим и один-к-одному. Итак, следующий шаг: [[step8|Шаг8. Отправка заказа]].