Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
PHP для продвинутых.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
12.54 Mб
Скачать

25. Модули

Модули создаются через gii-генератор.

Создадим модуль admin

После создания модуля admin, мы видим подсказу, что данный модуль необходимо включить в конфигурационный файл main.php

В рабочей папке появится каталог modules, в котором будет находится каталог admin. Рассмотрим структуру данного каталога.

Как видно из структуры, модуль может содержать независимые контроллеры и виды.

Из адресной строки модуль вызывается так:

папка_с_проектом/имя_модуля/контроллер/экшн/

26. Авторизация

Рассмотрим экшн actionLogin контроллера SiteController

actionLogin. Листинг 26.1

public function actionLogin()

{

$model=new LoginForm;

// валидация данных из формы

if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')

{

echo CActiveForm::validate($model);

Yii::app()->end();

}

// если пользователь отправил данные:

if(isset($_POST['LoginForm']))

{

$model->attributes=$_POST['LoginForm'];

// проверка и валидация логина, если проверки пройдены, делаем перенаправление на предыдущую страницу

if($model->validate() && $model->login())

$this->redirect(Yii::app()->user->returnUrl);

}

// display the login form

$this->render('login',array('model'=>$model));

}

$model->login – это вызов метода авторизации.

Валидация находится в функции rules.

Логины и пароли пользователей хранятся в классе UserIdentity (файл components/UserIdentity.php)

Метод authenticate класса UserIdentity. Листинг 26.2

public function authenticate()

{

$users=array(

// username => password

'demo'=>'demo',

'admin'=>'admin',

);

if(!isset($users[$this->username]))

$this->errorCode=self::ERROR_USERNAME_INVALID;

elseif($users[$this->username]!==$this->password)

$this->errorCode=self::ERROR_PASSWORD_INVALID;

else

$this->errorCode=self::ERROR_NONE;

return !$this->errorCode;

}

Как видно из листинга, первоначальные значения логина и пароля берутся из массива, а не из базы данных.

27. Контроль доступа на основе ролей

Поставим задачу. Необходимо определить четыре роли: guest, user, moderator, administrator и назначить их пользователям из базы данных с соответствующим полем role. Затем проверить доступ.

Первым делом настроим сам компонент. protected/config/main.php:

Настройка конфигурации. Листинг 27.1

'authManager' => array(

// Будем использовать свой менеджер авторизации

'class' => 'PhpAuthManager',

// Роль по умолчанию. Все, кто не админы, модераторы и юзеры — гости.

'defaultRoles' => array('guest'),

),

Создадим еще один конфигурационный файл, описывающий роли protected/config/auth.php::

protected/config/auth.php:. Листинг 27.2

return array(

'guest' => array(

'type' => CAuthItem::TYPE_ROLE,

'description' => 'Guest',

'bizRule' => null,

'data' => null

),

'user' => array(

'type' => CAuthItem::TYPE_ROLE,

'description' => 'User',

'children' => array(

'guest', // унаследуемся от гостя

),

'bizRule' => null,

'data' => null

),

'moderator' => array(

'type' => CAuthItem::TYPE_ROLE,

'description' => 'Moderator',

'children' => array(

'user', // позволим модератору всё, что позволено пользователю

),

'bizRule' => null,

'data' => null

),

'administrator' => array(

'type' => CAuthItem::TYPE_ROLE,

'description' => 'Administrator',

'children' => array(

'moderator', // позволим админу всё, что позволено модератору

),

'bizRule' => null,

'data' => null

),

);

Сделаем, чтобы Yii::app()->user->id возвращала id пользователя. Для этого немного изменим класс UserIdentity. protected/components/UserIdentity.php:

Расширенный UserIdentity. Листинг 27.3

class UserIdentity extends CUserIdentity {

// Будем хранить id.

protected $_id;

// Данный метод вызывается один раз при аутентификации пользователя.

public function authenticate(){

// Производим стандартную аутентификацию, описанную в руководстве.

$user = User::model()->find('LOWER(login)=?', array(strtolower($this->username)));

if(($user===null) || (md5($this->password)!==$user->password)) {

$this->errorCode = self::ERROR_USERNAME_INVALID;

} else {

// В качестве идентификатора будем использовать id, а не username,

// как это определено по умолчанию. Обязательно нужно переопределить

// метод getId(см. ниже).

$this->_id = $user->id;

// Далее логин нам не понадобится, зато имя может пригодится

// в самом приложении. Используется как Yii::app()->user->name.

// realName есть в нашей модели. У вас это может быть name, firstName

// или что-либо ещё.

$this->username = $user->realName;

$this->errorCode = self::ERROR_NONE;

}

return !$this->errorCode;

}

public function getId(){

return $this->_id;

}

}

Далее реализуем получение роли из БД при использовании Yii::app()->user->role. Для этого расширим CWebUser. protected/components/WebUser.php:

Класс WebUser. Листинг 27.4

class WebUser extends CWebUser {

private $_model = null;

function getRole() {

if($user = $this->getModel()){

// в таблице User есть поле role

return $user->role;

}

}

private function getModel(){

if (!$this->isGuest && $this->_model === null){

$this->_model = User::model()->findByPk($this->id, array('select' => 'role'));

}

return $this->_model;

}

}

Чтобы приложение использовало наш класс WebUser, необходимо сконфигурировать компонент user:

Конфигурация компонента user. Листинг 27.5

'user'=>array(

'class' => 'WebUser',

// …

),

Теперь у нас есть набор ролей и мы знаем роль пользователя. Осталось связать их. Для этого создадим класс PhpAuthManager. protected/components/PhpAuthManager.php:

Компонент PhpAuthManager. Листинг 27.6

class PhpAuthManager extends CPhpAuthManager{

public function init(){

// Иерархию ролей расположим в файле auth.php в директории config приложения

if($this->authFile===null){

$this->authFile=Yii::getPathOfAlias('application.config.auth').'.php';

}

parent::init();

// Для гостей у нас и так роль по умолчанию guest.

if(!Yii::app()->user->isGuest){

// Связываем роль, заданную в БД с идентификатором пользователя,

// возвращаемым UserIdentity.getId().

$this->assign(Yii::app()->user->role, Yii::app()->user->id);

}

}

}

Проверить роли можно так:

Проверка ролей. Листинг 27.7

if(Yii::app()->user->checkAccess('administrator')){

echo "hello, I'm administrator";

}

В модель User допишем константы ролей:

Модель user. Листинг 27.8

<?php

/**

* Модель User

*

* @property integer $id

* @property string $login

* @property string $password

* @property string $role

*/

class User extends CActiveRecord {

const ROLE_ADMIN = 'administrator';

const ROLE_MODER = 'moderator';

const ROLE_USER = 'user';

const ROLE_BANNED = 'banned';

public static function model($className=__CLASS__){

return parent::model($className);

}

public function tableName(){

return 'User';

}

protected function beforeSave(){

$this->password = md5($this->password);

return parent::beforeSave();

}

}

28. Ckeditor и CKfinder

Виджет CKeditor можно скачать по сылке:

http://www.yiiframework.com/extension/ckeditor-ckfinder

Любой элемент формы textarea мы можем превратить в редактор кода. Для этого вместо стандартного вызова textarea, пропишем следующий код:

Вызов виджета CKeditor. Листинг 28.1

<?php $this->widget('application.extensions.ckeditor.CKEditor', array( 'model'=>$model, 'attribute'=>'about', 'language'=>'ru', 'editorTemplate'=>'full', )); ?>

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]