0 追蹤者

管理文章

管理文章主要指的是在管理視圖中列出文章,讓我們能夠查看所有狀態的文章、更新和刪除它們。這些操作分別透過 admin 操作和 delete 操作來完成。由 Gii 產生的程式碼不需要太多修改。以下我們主要說明這兩個操作是如何實作的。

1. 以表格檢視列出文章

admin 操作以表格視圖顯示所有狀態的文章。該視圖支援排序和分頁。以下是 PostController 中的 actionAdmin() 方法

public function actionAdmin()
{
    $model=new Post('search');
    if(isset($_GET['Post']))
        $model->attributes=$_GET['Post'];
    $this->render('admin',array(
        'model'=>$model,
    ));
}

以上程式碼是由 Gii 工具產生,未經任何修改。它首先在 search 情境下建立一個 Post 模型。我們將使用此模型來收集使用者指定的搜尋條件。然後,我們會將使用者提供的資料(如果有的話)指派給模型。最後,我們使用該模型渲染 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 返回我們在 Post 類別中定義的 url 屬性的值。

提示: 在顯示文字時,我們呼叫 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 表格。這兩項任務都可以透過在 Post 模型類別中編寫 afterDelete 方法來實現,如下所示:

protected function afterDelete()
{
    parent::afterDelete();
    Comment::model()->deleteAll('post_id='.$this->id);
    Tag::model()->updateFrequency($this->tags, '');
}

以上程式碼非常直接:它首先刪除所有 post_id 與已刪除文章的 ID 相同的留言;然後更新 tbl_tag 表格中已刪除文章的 tags

提示: 我們在這裡必須顯式刪除已刪除文章的所有留言,因為 SQLite 實際上不支援外鍵約束。在支援此約束的 DBMS(例如 MySQL、PostgreSQL)中,可以設定外鍵約束,以便在刪除文章時,DBMS 自動刪除相關的留言。在這種情況下,我們的程式碼中不再需要這個顯式的刪除呼叫。

發現錯字或您認為此頁面需要改進嗎?
在 github 上編輯 !