准备好 Post
模型后,我们需要微调控制器 PostController
的操作和视图。在本节中,我们首先自定义 CRUD 操作的访问控制;然后,我们修改实现 create
和 update
操作的代码。
我们想要做的第一件事是自定义 访问控制,因为 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('*'),
),
);
}
上面的规则表明,所有用户都可以访问 index
和 view
操作,已认证的用户可以访问任何操作,包括 admin
操作。在任何其他情况下,用户应被拒绝访问。请注意,这些规则按它们在此处列出的顺序进行评估。第一个与当前上下文匹配的规则将做出访问决策。例如,如果当前用户是尝试访问帖子创建页面的系统所有者,则第二个规则将匹配,并且将允许用户访问。
create
和 update
操作 ¶create
和 update
操作非常相似。它们都需要显示 HTML 表单以收集用户输入、验证输入并将它们保存到数据库中。主要区别在于,update
操作将使用从数据库中找到的现有帖子数据预填充表单。出于这个原因,gii
生成一个部分视图 /wwwroot/blog/protected/views/post/_form.php
,该视图嵌入到 create
和 update
视图中以渲染所需的 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
表以反映标签频率的变化。我们可以在 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 上编辑它 !
updateFrequency 和其他 Tag 函数
此时,您的演示将停止工作,除非您从 yii/demos/blog/protected/models/Tag.php 类中获取三个函数
与其让您去那里,不如在这里提供它们
public function updateFrequency($oldTags, $newTags) { $oldTags=self::string2array($oldTags); $newTags=self::string2array($newTags); $this->addTags(array_values(array_diff($newTags,$oldTags))); $this->removeTags(array_values(array_diff($oldTags,$newTags))); } public function addTags($tags) { $criteria=new CDbCriteria; $criteria->addInCondition('name',$tags); $this->updateCounters(array('frequency'=>1),$criteria); foreach($tags as $name) { if(!$this->exists('name=:name',array(':name'=>$name))) { $tag=new Tag; $tag->name=$name; $tag->frequency=1; $tag->save(); } } } public function removeTags($tags) { if(empty($tags)) return; $criteria=new CDbCriteria; $criteria->addInCondition('name',$tags); $this->updateCounters(array('frequency'=>-1),$criteria); $this->deleteAll('frequency<=0'); }
一般错误 8:尝试写入只读数据库(SQLite)
如果您在 Linux 中使用 SQLite 并且收到上述错误,请注意,必须授予 .db 文件及其父文件夹(可能是 /data)的权限,否则您将收到上述错误。
请注册或登录以便评论。