Под управлением записями подразумевается отображение их списка в административном
разделе с возможностью просматривать записи с любым статусом, редактировать и
удалять их. Эта функциональность реализуется в действиях admin
и delete
соответственно. Код, сгенерированный при помощи Gii
почти не нуждается в
изменениях. Ниже мы объясним, как реализованы эти действия.
Действие admin
выводит записи со всеми статусами в виде таблицы,
разбитой на несколько страниц и поддерживающей сортировку по нескольким колонкам.
Далее приведён метод actionAdmin()
контроллера PostController
:
public function actionAdmin()
{
$model=new Post('search');
if(isset($_GET['Post']))
$model->attributes=$_GET['Post'];
$this->render('admin',array(
'model'=>$model,
));
}
Данный код полностью сгенерирован Gii
. Сначала создаётся модель Post
со сценарием
search
, которую мы будем использовать для
сбора критериев поиска, указанных пользователем. Далее мы присваиваем
данные, введённые пользователем, модели. И, наконец, мы выводим отображение
admin
, используя модель.
Ниже приведён код отображения admin
:
$this->breadcrumbs=array( 'Manage Posts', ); <h1>Manage Posts</h1> $this->widget('zii.widgets.grid.CGridView', array( 'dataProvider'=>$model->search(), 'filter'=>$model, 'columns'=>array( array( 'name'=>'title', 'type'=>'raw', 'value'=>'CHtml::link(CHtml::encode($data->title), $data->url)' ), array( 'name'=>'status', 'value'=>'Lookup::item("PostStatus",$data->status)', 'filter'=>Lookup::items('PostStatus'), ), array( 'name'=>'create_time', 'type'=>'datetime', 'filter'=>false, ), array( 'class'=>'CButtonColumn', ), ), ));
Для вывода записей мы используем компонент CGridView, который
разбивает данные на страницы и позволяет их сортировать по столбцам.
Наше изменение касается, главным образом, отображения каждого столбца.
К примеру, для столбца title
мы указываем, что он должен содержать
ссылку на просмотр записи. Выражение $data->url
возвращает значение
свойства url
, которое мы определяем в классе Post
.
Подсказка: При выводе текста мы используем CHtml::encode() для кодирования сущностей HTML. Это позволяет избежать атак через межсайтовый скриптинг.
В data grid admin
в каждой строке есть кнопка «Удалить», удаляющая соответствующую
запись. Действие delete
выглядит следующим образом:
public function actionDelete()
{
if(Yii::app()->request->isPostRequest)
{
// we only allow deletion via POST request
$this->loadModel()->delete();
if(!isset($_GET['ajax']))
$this->redirect(array('index'));
}
else
throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
}
Приведённый выше код полностью сгенерирован Gii
. Остановимся подробнее на
проверке $_GET['ajax']
. В виджете CGridView сортировка, постраничная
разбивка и удаление по умолчанию реализованы с использованием AJAX. То есть при
выполнении перечисленных действий страница перезагружаться не будет.
Виджет может работать и без AJAX (если свойство ajaxUpdate
выставлено в
false
или отключен JavaScript). В действии delete
при AJAX запросе перенаправление
производиться не должно.
Удаление записи должно вызывать удаление всех комментариев к ней. Вдобавок,
мы должны обновить теги в таблице tbl_tag
. Обе задачи могут быть выполнены
в методе afterDelete
модели Post
:
protected function afterDelete()
{
parent::afterDelete();
Comment::model()->deleteAll('post_id='.$this->id);
Tag::model()->updateFrequency($this->tags, '');
}
Код, приведённый выше не сложен: сначала удаляются все комментарии, чей
post_id
равен ID удаляемой записи. Далее обновляется таблица tbl_tag
.
Подсказка: Мы удаляем комментарии удаляемой записи в коде, так как SQLite не поддерживает ограничения по внешнему ключу. В СУБД, которые данное ограничение поддерживают (например, MySQL или PostgreSQL), можно использовать каскадное удаление комментариев в случае удаления записи. В этом случае нет необходимости удалять комментарии в коде.
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.