0 follower

Управление записями

Под управлением записями подразумевается отображение их списка в административном разделе с возможностью просматривать записи с любым статусом, редактировать и удалять их. Эта функциональность реализуется в действиях admin и delete соответственно. Код, сгенерированный при помощи Gii почти не нуждается в изменениях. Ниже мы объясним, как реализованы эти действия.

1. Отображение записей в виде таблицы

Действие 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:

<?php
$this->breadcrumbs=array(
    'Manage Posts',
);
?>
<h1>Manage Posts</h1>
 
<?php $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. Это позволяет избежать атак через межсайтовый скриптинг.

2. Удаление записей

В 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 !