日志的创建与更新
准备好了 Post 模型,我们现在需要调整控制器 PostController 的动作和视图了。在这一节里,我们首先自定义CRUD操作的访问权限控制;然后我们修改代码实现 创建 与 更新 操作。
自定义访问控制
我们想做的第一件事是自定义 访问控制(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('*'), ), ); }
上面的规则说明:所有用户均可访问 index 和 view 动作,已通过身份验证的用户可以访问任意动作,包括 admin 动作。在其他场景中,应禁止用户访问。注意这些规则将会按它们在此列出的顺序计算。第一条匹配当前场景的规则将决定访问权。例如,如果当前用户是系统所有者,他想尝试访问日志创建页,第二条规则将匹配成功并授予此用户权限。
自定义 创建 和 更新 操作
创建 和 更新 操作非常相似。他们都需要显示一个HTML表单用于收集用户的输入的信息,然后对其进行验证,然后将其存入数据库。主要的不同是 更新 操作需要把从数据库找到的已存在的日志数据重现在表单中。鉴于此,yiic 工具创建了一个局部视图 /wwwroot/blog/protected/views/post/_form.php ,它会插入 创建 和 更新 视图来渲染所需的HTML表单。
我们先修改 _form.php 这个文件,使这个HTML表单只收集我们想要的输入:title, content, tags 和 status。我们使用文本域收集前三个属性的输入,还有一个下拉列表用来收集 status 的输入。此下拉列表的选项值就是可用的日志状态文本。
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 文件。