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