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 scenario, який ми будемо використовувати для збору критеріїв пошуку, вказаних користувачем. Далі ми присвоюємо дані, введені користувачем, моделі. І, нарешті, ми виводимо відображення 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. Видалення записів

У таблиці данних 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 !