管理文章主要指的是在管理視圖中列出文章,讓我們能夠查看所有狀態的文章、更新和刪除它們。這些操作分別透過 admin
操作和 delete
操作來完成。由 Gii
產生的程式碼不需要太多修改。以下我們主要說明這兩個操作是如何實作的。
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
檢視的程式碼
$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
返回我們在 Post
類別中定義的 url
屬性的值。
提示: 在顯示文字時,我們呼叫 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
表格。這兩項任務都可以透過在 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 上編輯 !
為了留言,請註冊或登入。