管理文章主要指在管理视图中列出文章,该视图允许我们查看所有状态的文章,并更新和删除它们。它们分别由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 上编辑它 !
注册 或 登录 以发表评论。