【发布时间】:2014-02-07 23:58:17
【问题描述】:
我正在尝试使用 CakeEvents 在我的 CakePHP 应用程序中构建成就系统。我一直在使用以下网站来帮助我整理活动:http://martinbean.co.uk/blog/2013/11/22/getting-to-grips-with-cakephps-events-system/
在我的应用中,成就称为徽章,可以授予用户。这些徽章是根据将徽章与蛋糕活动相关联的规则授予的。
因此,例如,如果用户创建了一个帖子,这将触发 Model.Post.add 事件,该事件应检查该事件是否存在任何规则,如果存在,则参数是否匹配,如果所有检查均已成功,则再次奖励连接到该规则的徽章给用户。
架构包含以下表格:
用户
- 身份证
- 用户名
- 密码
帖子
- 身份证
- 标题
- 内容
- 已创建
- 修改
- user_id
徽章
- 身份证
- 标题
- 说明
事件
- 身份证
- 标题
- 姓名
event_badges
- 身份证
- event_id
- badge_id
徽章用户
- 身份证
- badge_id
- user_id
希望这一切都说得通。下面是展示它们如何连接的模型。
用户.php
class User extends AppModel
{
public $name = 'User';
public $hasMany = array(
'Post', 'Badge'
);
public $belongsTo = array(
'BadgeUser'
);
}
徽章.php
class Badge extends AppModel {
public $hasMany = array(
'BadgeUser'
);
public $actsAs = array('Containable');
}
事件.php
class Event extends AppModel {
public $hasMany = array(
'EventBadge'
);
public $actsAs = array('Containable');
}
EventBadge.php
class ActionBadge extends AppModel {
public $belongsTo = array(
'Action', 'Badge'
);
public $actsAs = array('Containable');
}
BadgeUser.php
class BadgeUser extends AppModel {
public $belongsTo = array(
'Badge', 'User'
);
public $actsAs = array('Containable');
}
** 如果您认为架构不正确,无法实现此问题中描述的内容,请随时发表评论。**
所以示例徽章可能是:
- 标题:第一个帖子,说明:因创建帖子而获奖
- 标题:10 个帖子,描述:因创建 10 个帖子而获奖
- 标题:编辑,描述:编辑帖子
- 标题:删除者,描述:删除帖子
以及事件表中的一些示例规则:
- 标题:添加帖子、事件 Model.Post.add
- 标题:编辑帖子,事件:Model.Post.edit
- 标题:删除帖子,事件:Model.Post.delete
- 标题:查看帖子,事件:Model.Post.view
如您所见,事件与上述徽章相关联,并且事件是使用 CakeEvents 系统调用的。
好的,所以当一个人做某事时,比如说保存一个新帖子,我在 Post 模型中有以下内容:
public function afterSave($created, $options = array()) {
if ($created) {
$event = new CakeEvent('Model.Post.add', $this, array(
'id' => $this->id,
'data' => $this->data[$this->alias]
));
$this->getEventManager()->dispatch($event);
}
}
第一个问题是,如何将不同的事件传递给 afterSave?因为控制器中的 Add 和 Edit 方法都会触发这个...
然后我在/app/Event 中有一个 PostListener.php 文件
class PostListener implements CakeEventListener {
public function implementedEvents() {
return array(
'Model.Post.add' => 'postAdded',
'Model.Post.edit' => 'postEdited',
'Model.Post.view' => 'postViewed',
'Model.Post.delete' => 'postDeleted',
);
}
public function postAdded(CakeEvent $event) {
$this->Badge->awardBadge($badgeId, $userId);
}
public function postEdited(CakeEvent $event) {
}
public function postViewed(CakeEvent $event) {
}
public function postDeleted(CakeEvent $event) {
}
}
那么下一个问题是如何将事件侦听器链接回我的事件表?
然后奖励与该动作相关的徽章?请注意,有些人需要进行额外的检查,例如用户必须创建 10 个帖子才能获得 10 个帖子的标记,而不仅仅是因为他们创建了一个帖子。
在 Badge.php 模型中,我有以下函数来奖励徽章:
public function awardBadge($badgeId, $userId) {
$controlFind = $this->BadgeUser->find(
'first',
array(
'conditions' => array(
'badge_id' => $badgeId,
'user_id' => $userId,
)
)
);
if(!$controlFind) {
$temp = array(
'BadgeUser' => array(
'badge_id' => $badgeId,
'user_id' => $userId,
'created' => date('Y-m-d H:i:s')
)
);
$collection[] = $temp;
return $this->BadgeUser->saveAll($collection, array('validate' => false));
}
}
所以当事情与数据库规则匹配时,我需要从侦听器运行上面的代码。只是努力让这一切粘在一起。
【问题讨论】: