0 关注者

创建和更新帖子

准备好 Post 模型后,我们需要微调控制器 PostController 的操作和视图。在本节中,我们首先自定义 CRUD 操作的访问控制;然后,我们修改实现 createupdate 操作的代码。

1. 自定义访问控制

我们想要做的第一件事是自定义 访问控制,因为 gii 生成的代码不符合我们的需求。

我们修改文件 /wwwroot/blog/protected/controllers/PostController.php 中的 accessRules() 方法,如下所示,

public function accessRules()
{
    return array(
        array('allow',  // allow all users to perform 'list' and 'show' actions
            'actions'=>array('index', 'view'),
            'users'=>array('*'),
        ),
        array('allow', // allow authenticated users to perform any action
            'users'=>array('@'),
        ),
        array('deny',  // deny all users
            'users'=>array('*'),
        ),
    );
}

上面的规则表明,所有用户都可以访问 indexview 操作,已认证的用户可以访问任何操作,包括 admin 操作。在任何其他情况下,用户应被拒绝访问。请注意,这些规则按它们在此处列出的顺序进行评估。第一个与当前上下文匹配的规则将做出访问决策。例如,如果当前用户是尝试访问帖子创建页面的系统所有者,则第二个规则将匹配,并且将允许用户访问。

2. 自定义 createupdate 操作

createupdate 操作非常相似。它们都需要显示 HTML 表单以收集用户输入、验证输入并将它们保存到数据库中。主要区别在于,update 操作将使用从数据库中找到的现有帖子数据预填充表单。出于这个原因,gii 生成一个部分视图 /wwwroot/blog/protected/views/post/_form.php,该视图嵌入到 createupdate 视图中以渲染所需的 HTML 表单。

我们首先更改 _form.php 文件,以便 HTML 表单只收集我们想要的输入:titlecontenttagsstatus。我们使用纯文本字段来收集前三个属性的输入,并使用下拉列表来收集 status 的输入。下拉列表选项是可能的帖子状态的文本显示

<?php echo $form->dropDownList($model,'status',Lookup::items('PostStatus')); ?>

在上面,我们调用 Lookup::items('PostStatus') 以调回帖子状态列表。

然后我们修改 Post 类,以便它可以在保存帖子到数据库之前自动设置一些属性(例如 create_timeauthor_id)。我们覆盖 beforeSave() 方法,如下所示,

protected function beforeSave()
{
    if(parent::beforeSave())
    {
        if($this->isNewRecord)
        {
            $this->create_time=$this->update_time=time();
            $this->author_id=Yii::app()->user->id;
        }
        else
            $this->update_time=time();
        return true;
    }
    else
        return false;
}

当我们保存帖子时,我们想要更新 tbl_tag 表以反映标签频率的变化。我们可以在 afterSave() 方法中执行此操作,该方法在帖子成功保存到数据库后由 Yii 自动调用。

protected function afterSave()
{
    parent::afterSave();
    Tag::model()->updateFrequency($this->_oldTags, $this->tags);
}
 
private $_oldTags;
 
protected function afterFind()
{
    parent::afterFind();
    $this->_oldTags=$this->tags;
}

在实现中,因为我们想要检测用户是否更改了标签(以防他正在更新现有帖子),我们需要知道旧标签是什么。出于这个原因,我们还编写了 afterFind() 方法,以将旧标签保存在变量 _oldTags 中。afterFind() 方法在 AR 记录被填充了来自数据库的数据后由 Yii 自动调用。

我们不会详细介绍 Tag::updateFrequency() 方法。有兴趣的读者可以参考文件 /wwwroot/yii/demos/blog/protected/models/Tag.php

发现错别字或您认为此页面需要改进?
在 github 上编辑它 !