0 follower

日志的创建与更新

准备好了 Post 模型,我们现在需要调整控制器 PostController 的动作和视图了。在这一节里,我们首先自定义CRUD操作的访问权限控制;然后我们修改代码实现 创建更新 操作。

1. 自定义访问控制

我们想做的第一件事是自定义 访问控制(Access control) ,因为 yiic 工具生成的代码并不符合我们的需求。

我们将 /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. 自定义 创建更新 操作

创建更新 操作非常相似。他们都需要显示一个HTML表单用于收集用户的输入的信息,然后对其进行验证,然后将其存入数据库。主要的不同是 更新 操作需要把从数据库找到的已存在的日志数据重现在表单中。鉴于此,yiic 工具创建了一个局部视图 /wwwroot/blog/protected/views/post/_form.php ,它会插入 创建更新 视图来渲染所需的HTML表单。

我们先修改 _form.php 这个文件,使这个HTML表单只收集我们想要的输入:title, content, tagsstatus。我们使用文本域收集前三个属性的输入,还有一个下拉列表用来收集 status 的输入。此下拉列表的选项值就是可用的日志状态文本。

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

在上面的代码中,我们调用了 Lookup::items('PostStatus') 以带回日志状态列表。

然后我们修改 Post 类,使它可以在日志被存入数据库前自动设置几个属性 (例如 create_time, author_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 表以反映 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;
}

在这个实现中,因为我们想检测出用户在更新现有日志的时候是否修改了 Tag ,我们需要知道原来的 Tag 是什么, 鉴于此,我们还写了一个 afterFind() 方法把原有的 Tag 信息保存到变量 _oldTags 中。方法 afterFind() 会在一个 AR 记录被数据库中的数据填充时自动被 Yii 调用。

这里我们不再列出 Tag::updateFrequency() 方法的细节,读者可以参考 /wwwroot/yii/demos/blog/protected/models/Tag.php 文件。

Found a typo or you think this page needs improvement?
Edit it on github !