====== Шаг4.1 Управление списком пользователей ====== ===== Создание класса User ===== Т.к. мы уже умеем создавать модели, контроллеры и шаблоны, то позволим себе немного расслабится и воспользоваться возможностью [[limb3:ru:packages:constructor#%D0%B3%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F_%D1%81%D1%83%D1%89%D0%BD%D0%BE%D1%81%D1%82%D0%B5%D0%B9_%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F| генерации сущностей]]: $ php ./lib/limb/limb.php entity_create Project directory [/www/limb-example-shop]: Limb directory [/www/limb-example-shop/lib/]: Table name (could be 'all'): user После выполнения этих действий у нас должны были появится модель, контроллер и шаблоны, построенные по таблице **user**. ==== Код класса User ==== Теперь можно дописать код класса User (shop/src/model/User.class.php): [...] protected $_default_sort_params = array('name' => 'ASC'); protected $password; [...] protected function _createValidator() { $validator = new lmbValidator(); $validator->addRequiredRule('login'); $validator->addRequiredRule('email'); $validator->addRequiredRule('name'); lmb_require('src/validation/UserUniqueFieldRule.class.php'); $validator->addRule(new UserUniqueFieldRule('login', $this)); $validator->addRule(new UserUniqueFieldRule('email', $this)); lmb_require('limb/validation/src/rule/lmbEmailRule.class.php'); $validator->addRule(new lmbEmailRule('email')); return $validator; } protected function _onBeforeSave() { $this->_generatePassword(); } protected function _generatePassword() { if($this->password) $this->setHashedPassword(self :: cryptPassword($this->password)); } static function cryptPassword($password) { return md5($password); } [...] Создаваемый в методе _createValidator() валидатор проверяет, что поля email и login должны быть заполнены и иметь уникальные значения. Последнее обеспечивается за счет использования правила %%UserUniqueFieldRule%%. Правило lmbEmailRule удостоверяется, что введенное в поле значение является электронным адресом. Обратите внимание на метод **_onBeforeSave()**. Это так называемый метод расширения класса lmbActiveRecord, который дочерние классы могут использовать чтобы выполнять необходимые действия, например, перед сохранением новой записи, перед обновлением существующей, после сохранения и т.д. Список методов расширения класса lmbActiveRecord есть в разделе [[limb3:ru:packages:active_record:enhancement|"Расширение поведения базового класса lmbActiveRecord"]]. В нашем случае мы использовали этот метод, чтобы шифровать поле **password** и формировать значение поля **hashed_password**. Таким образом мы будем хранить только хешированный пароль, а обновление хешированного пароля будет происходить только, если в поле password есть новое значение. ===== Доработка шаблонов и контроллера для управления пользователями ===== ==== Добавление ссылки в навигацию ==== Добавим ссылку в панель навигации. Файл shop/settings/navigation.conf.php^ [...] $conf[lmbCmsUserRoles :: ADMIN][0]['children'][] = array( "title" => "Пользователи", "url" => "/admin_user/", "icon" => "/shared/cms/images/icons/user.png", ); ==== Шаблоны ==== Шаблоны для действий create, edit и display просты и не составят большого труда. Особенно, если учесть, что они уже сгенерированы. Остановимся только на шаблоне с полями формы: Файл shop/template/admin_user/form_fields.phtml:
{{label for="name"}}Имя:{{/label}} {{input id="name" name="name" type="text" title="name"/}}
{{label for="login"}}Логин:{{/label}} {{input id="login" name="login" type="text" title="login"/}}
{{label for="password"}}Пароль:{{/label}} {{input id="password" name="password" type="text" title="hashed_password"/}}
{{label for="email"}}email:{{/label}} {{input id="email" name="email" type="text" title="email"/}}
{{label for="address"}}Адрес:{{/label}} {{wysiwyg id="address" name="address" width="100%" height="300px" title="address"/}}
Тут есть два момента: * мы использовались автогенерацией вкладок * вместо hashed_password у нас есть поле password, которое, как мы помним хэшируется перед сохранением объекта ===== Валидация пользователя ===== Реализация пользователей должна отвечать следующим требованиям: * В системе не должно быть пользователей с одинаковыми логинами и email-адресами. * Пароли пользователей не должны храниться в базе данных в открытом виде. При помощи класса **%%UserUniqueFieldRule%%** мы будем проверять наличие одного уникального пользователя со значением какого-либо поля. Это правило валидации потом будет использоваться в классе **User**. Файл %%shop/src/validation/UserUniqueFieldRule.class.php%%: current_user = $current_user; parent :: __construct($field); } function check($value) { $criteria = new lmbSQLFieldCriteria($this->field_name, $value); if(!$this->current_user->isNew()) $criteria->addAnd(lmbSQLCriteria::notEqual('id', $this->current_user->getId())); if(User :: findOne($criteria)) $this->error('Пользователь со значением поля {Field} уже существует'); } } Класс %%UserUniqueFieldRule%% получает в конструкторе название поля, которое должно быть уникальным, и ссылку на текущего пользователя. Текущий пользователь понадобится нам при редактировании. Класс **%%lmbSingleFieldRule%%** является базовым для правил валидации одного поля. Файл класса можно найти по пути limb/validation/src/rule/lmbSingleFieldRule.class.php Дочерние классы должны перекрывать метод **check($value)**, где $value - значение поля, которое необходимо проверить. Следует отметить, что check($value) не вызывается, если $value не содержит значимого значения. Поэтому совместно с этим правилом (его дочерними) рекомендуется использовать также правило **lmbRequiredFieldRule**. Об этом ты также упомянем чуть ниже при описании кода класса User. При помощи [[limb3:ru:packages:active_record:find|find-метода класса lmbActiveRecord]] делается запрос к базе данных. В качестве второго параметра вместо $params можно передавать объект критерии, которая будет накладываться на выборку. Критерия - это объектная форма условия. В нашем случае использовался класс **lmbSQLFieldCriteria**, который принимает в конструкторе название поля и значение (по-умолчанию для этой пары формируется условие равенства). Использование критериев позволяет не думать о экранировании данных в SQL-запросах. Класс **lmbSQLCriteria** является фабрикой для критерий. Вы можете подробнее ознакомиться с классами [[limb3:ru:packages:dbal:criteria|Criteria]], однако это необязательно для понимания данного примера. Метод lmbSingleFieldRule :: **error($error_string, $values = array())** добавляет ошибку в список ошибок валидации. Выражения вида {Field} будут заменены в процессе работы на реальные имена полей формы, с которой производится создание/редактирование пользователя. ===== Далее ===== Мы рекомендуем вам, при помощи этой новой функциональности, добавить себе пользователя и приступить к следующему шагу: [[step4-2|"Шаг4.2 Аутентификация пользователей"]].