Создание и редактирование записей ================================= После того, как мы закончили с моделью `Post`, займёмся контроллером `PostController` и его отображениями. В данном разделе мы настроим правила доступа операций CRUD. Затем изменим код, отвечающий за `создание`(`create`) и `обновление`(`update`). Настройка правил доступа ------------------------ Первое, что мы запланировали — настройка [прав доступа](/doc/guide/ru/topics.auth#access-control-filter). Код, сгенерированный при помощи `gii` нам не подойдёт. Необходимо изменить метод `accessRules()` в файле `/wwwroot/blog/protected/controllers/PostController.php` следующим образом: ~~~ [php] public function accessRules() { return array( array('allow', // позволим всем пользователям выполнять действия 'list' и 'show' 'actions'=>array('index', 'view'), 'users'=>array('*'), ), array('allow', // позволим аутентифицированным пользователям выполнять любые действия 'users'=>array('@'), ), array('deny', // остальным запретим всё 'users'=>array('*'), ), ); } ~~~ Описанные выше правила разрешают всем пользователям выполнять действия `index` и `view`. Аутентифицированным — любые действия, включая `admin`. Всем остальным пользователям запрещено всё. Стоит отметить, что правила применяются в порядке их описания. Первое сработавшее правило определяет, давать доступ или не давать. К примеру, если текущий пользователь является владельцем системы и пытается зайти на страницу создания записи, будет применено второе правило и доступ будет разрешён. Правки в действиях `create` и `update` -------------------------------------- Операции `create` и `update` довольно похожи. В обоих случаях требуется вывести HTML форму для сбора данных, вводимых пользователем. Также требуется валидация и сохранение данных в БД. Главное отличие в том, что при `update` форма будет заполняться данными о редактируемой записи. По этой причине `gii` генерирует вложенное отображение `/wwwroot/blog/protected/views/post/_form.php`, которое включается как в отображение `create`, так и отображение `update` для вывода HTML формы. Для начала изменим файл `_form.php` таким образом, чтобы форма собирала только нужные нам данные: `title`, `content`, `tags` и `status`. Для первых трёх атрибутов мы используем текстовые поля. Для `status` — выпадающий список со всеми возможными состояниями записи: ~~~ [php] dropDownList($model,'status',Lookup::items('PostStatus')); ?> ~~~ В приведённом коде для получения списка статусов используется вызов `Lookup::items('PostStatus')`. Далее изменим класс `Post` таким образом, чтобы он автоматически выставлял некоторые атрибуты (такие, как `create_time` и `author_id`) непосредственно перед сохранением записи в БД. Перекроем метод `beforeSave()`: ~~~ [php] protected function beforeSave() { if(parent::beforeSave()) { if($this->isNewRecord) { $this->create_time=$this->update_time=time(); $this->author_id=Yii::app()->user->id; } else $this->update_time=time(); return true; } else return false; } ~~~ При сохранении записи мы хотим также обновить информацию о частоте использования тегов в таблице `tbl_tag`. Мы можем реализовать это в методе `afterSave()`, который автоматически вызывается после успешного сохранения записи в БД. ~~~ [php] protected function afterSave() { parent::afterSave(); Tag::model()->updateFrequency($this->_oldTags, $this->tags); } private $_oldTags; protected function afterFind() { parent::afterFind(); $this->_oldTags=$this->tags; } ~~~ Так как необходимо определить, менял ли пользователь теги при редактировании записи, нам понадобятся старые теги. Для этого мы реализуем метод `afterFind()`, который записывает старые теги в свойство `_oldTags`. Метод `afterFind()` вызывается автоматически при заполнении модели AR данными, полученными из БД. Здесь мы не будем детально рассматривать метод `Tag::updateFrequency()`. Заинтересованные читатели могут ознакомиться с ним в файле `/wwwroot/yii/demos/blog/protected/models/Tag.php`.