我'm attempting to build an achievements system in my CakePHP app using CakeEvents. I'一直在使用以下网站帮助我把事件放在一起:http://martinbean.co.uk/blog/2013/11/22/getting-to-grips-with-cakephps-events-system/
在我的应用程序中,成就称为徽章,可以授予用户 . 这些徽章是根据将徽章链接到Cake事件的规则授予的 .
因此,例如,如果用户创建帖子,则会触发 Model.Post.add
事件,该事件应检查该事件是否存在任何规则,如果是,则参数匹配,如果所有检出都匹配,则再次授予连接到该规则的徽章给用户 .
该模式包含以下表格:
用户
-
id
-
用户名
-
密码
帖子
-
id
-
Headers
-
内容
-
已创建
-
已修改
-
user_id
徽章
-
id
-
Headers
-
说明
事件
-
id
-
Headers
-
名字
event_badges
-
id
-
event_id
-
badge_id
badge_users
-
id
-
badge_id
-
user_id
希望一切都有意义 . 以下是展示他们如何联系的模型 .
user.php的
class User extends AppModel
{
public $name = 'User';
public $hasMany = array(
'Post', 'Badge'
);
public $belongsTo = array(
'BadgeUser'
);
}
Badge.php
class Badge extends AppModel {
public $hasMany = array(
'BadgeUser'
);
public $actsAs = array('Containable');
}
Event.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');
}
**如果您认为架构不正确以实现此问题中描述的内容,请随意发表评论 . **
所以示例徽章可能是:
-
Headers :第一篇文章,描述:因创建帖子而获奖
-
Headers :10篇帖子,描述:创建10个帖子获颁的奖项
-
Headers :编辑,描述:编辑帖子
-
Headers :删除,描述:删除帖子
以及Events表中的一些示例规则:
-
Headers :添加帖子,事件Model.Post.add
-
Headers :编辑帖子,事件:Model.Post.edit
-
Headers :删除帖子,事件:Model.Post.delete
-
Headers :查看帖子,事件: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);
}
}
The first question is, how do I pass different events to the afterSave? As both Add and Edit methods in the controller would fire this...
然后我在 /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) {
}
}
So the next question is how do I link the event listener back up to my Events table?
And then award the badge connected to that action? Noting that some will need to do extra checks like a user must of created 10 posts to achieve the 10 Posts badged and not just because they have created a post.
在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));
}
}
So I need to run the code above from the listener when things match up with the DB rules. Just struggling to make it all stick together.
2 回答
我认为你的数据库模式可能会因事件的概念而变得复杂 . 就个人而言,我有一个
badges
表存储徽章 Headers 和描述(如果需要,还有图像路径) . 然后,我会有一个与每个徽章相对应的事件监听器,因此会涉及一定程度的手工劳动 .让我们想一个示例场景 . 假设当用户发布100次时会颁发徽章 . 因此,当您保存帖子时,您的
Post
模型会触发事件:然后,您可以创建相应的处理程序:
这是一个粗略的例子,但它希望能引导你朝着正确的方向前进 .
如果有什么要让我清理的话,请告诉我,我会尽我所能 .
The first question - 区分新帖子和编辑
要区分添加和编辑,您需要在创建CakeEvent时传递
$created
参数 . 像这样的东西:您应该在事件数据中添加以后需要处理的所有数据并匹配您的规则 . 如果您认为需要对模型对象进行一些查询,您甚至可以添加模型对象本身 .
Second Question - 如何将事件处理链接到Events表
在Event侦听器中,您可以使用ClassRegistry来获取Event模型的实例(以及您需要的任何其他模型) . 您可以进行规则匹配,一旦获得所需的所有数据,就可以将徽章保存到数据库中 .
由于您现在知道它是编辑还是新帖子(来自事件 - >数据),您可以采取适当的措施 .
编辑ID我猜你可以把Auth组件作为登录用户 . 因此,当您拥有它时,您可以使用它从数据库中读取编辑器所需的内容 .
总结:当您发送事件时,使用事件数据传递您在侦听器中需要的所有信息 . 事件可以携带更多信息,而不仅仅是它们的名称以及它们被触发的事实 . 您可以发送然后查看整个"context" .
在侦听器中,充分利用从事件和当前登录的用户ID或帖子作者获得的数据,执行您需要执行的匹配,然后为相应的用户保存徽章 .
希望这是你在找什么:)