-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathplugin.php
161 lines (133 loc) · 6.37 KB
/
plugin.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<?php
// Copyright 2013 Toby Zerner, Simon Zerner
// This file is part of esoTalk. Please see the included license file for usage information.
if (!defined("IN_ESOTALK")) exit;
ET::$pluginInfo["MemberNotifications"] = array(
"name" => "Member Notifications",
"description" => "Allows users to follow members and get notified about new posts by them.",
"version" => ESOTALK_VERSION,
"author" => "Toby Zerner",
"authorEmail" => "[email protected]",
"authorURL" => "http://esotalk.org",
"license" => "GPLv2",
"dependencies" => array(
"esoTalk" => "1.0.0g4"
)
);
class ETPlugin_MemberNotifications extends ETPlugin {
// Setup: add a follow column to the member_member table.
public function setup($oldVersion = "")
{
$structure = ET::$database->structure();
$structure->table("member_member")
->column("follow", "bool", 0)
->exec(false);
return true;
}
public function init()
{
// Add the postMember activity type.
ET::activityModel();
ETActivityModel::addType("postMember", array(
"notification" => array(__CLASS__, "postMemberNotification"),
"email" => array(__CLASS__, "postMemberEmail")
));
// Define the postMember email language text.
ET::define("email.postMember.body", "<p><strong>%1\$s</strong> has posted in a conversation: <strong>%2\$s</strong></p><hr>%3\$s<hr><p>To view the new activity, check out the following link:<br>%4\$s</p>");
ET::define("email.postMember.subject", "There is a new post by %1\$s");
}
// Add a follow button to each member's profile.
public function handler_memberController_initProfile($sender, $member, $panes, $controls, $actions)
{
if (!ET::$session->user) return;
$starred = @$member["follow"];
$url = URL("member/follow/".$member["memberId"]."?token=".ET::$session->token."&return=".urlencode(ET::$controller->selfURL));
$actions->add("follow", "<a href='$url' class='button' title='".T("Follow to receive notifications")."' data-id='{$member["memberId"]}'><i class='star icon-star".($starred ? "" : "-empty")."'></i> <span>".($starred ? T("Following") : T("Follow"))."</span></a>", 0);
}
// Add an action to toggle the following status of a member.
public function action_memberController_follow($controller, $memberId = "")
{
if (!ET::$session->user or !$controller->validateToken()) return;
// Make sure the member that we're trying to follow exists.
if (!ET::SQL()->select("memberId")->from("member")->where("memberId", (int)$memberId)->exec()->numRows()) return;
// Work out if we're already followed or not, and switch to the opposite of that.
$followed = !ET::SQL()
->select("follow")
->from("member_member")
->where("memberId1", ET::$session->userId)
->where("memberId2", (int)$memberId)
->exec()
->result();
// Write to the database.
ET::memberModel()->setStatus(ET::$session->userId, $memberId, array("follow" => $followed));
// Normally, redirect back to the member profile.
if ($controller->responseType === RESPONSE_TYPE_DEFAULT) redirect(URL("member/".$memberId));
// Otherwise, set a JSON var.
$controller->json("follow", $followed);
$controller->render();
}
// Send out notifications to people who have starred the member that made a post.
public function handler_conversationModel_addReplyAfter($sender, $conversation, $postId, $content)
{
// Only continue if this is the first post.
if ($conversation["countPosts"] > 1) return;
// We get all members who have starred the post author and have no unread posts in the conversation.
$sql = ET::SQL()
->from("member_member mm2", "mm2.memberId2=:userId AND mm2.memberId1=m.memberId AND mm2.follow=1 AND mm2.memberId1!=:userId", "inner")
->from("member_conversation co", "co.conversationId=:conversationId AND co.type='member' AND co.id=m.memberId", "left")
->where("co.lastRead IS NULL OR co.lastRead>=:posts")
->bind(":conversationId", $conversation["conversationId"])
->bind(":posts", $conversation["countPosts"] - 1)
->bind(":userId", ET::$session->userId);
$members = ET::memberModel()->getWithSQL($sql);
$data = array(
"conversationId" => $conversation["conversationId"],
"postId" => $postId,
"title" => $conversation["title"]
);
$emailData = array("content" => $content);
foreach ($members as $member) {
// Check if this member is allowed to view this conversation before sending them a notification.
$sql = ET::SQL()
->select("conversationId")
->from("conversation c")
->where("conversationId", $conversation["conversationId"]);
ET::conversationModel()->addAllowedPredicate($sql, $member);
if (!$sql->exec()->numRows()) continue;
ET::activityModel()->create("postMember", $member, ET::$session->user, $data, $emailData);
}
}
public function handler_conversationModel_createAfter($sender, $conversation, $postId, $content)
{
if (!$postId) return; // the conversation is a draft
$this->handler_conversationModel_addReplyAfter($sender, $conversation, $postId, $content);
}
// Add the "email me when someone replies to a conversation in a channel I have followed" field to the settings page.
public function handler_settingsController_initGeneral($sender, $form)
{
$form->setValue("postMember", ET::$session->preference("email.postMember"));
$form->addField("notifications", "postMember", array(__CLASS__, "fieldEmailPostMember"), array($sender, "saveEmailPreference"), array("after" => "post"));
}
public static function fieldEmailPostMember($form)
{
return "<label class='checkbox'>".$form->checkbox("postMember")." <i class='star icon-star'></i> ".T("Email me when there is a new post by a member I have followed")."</label>";
}
// Format the postMember notification.
public static function postMemberNotification(&$item)
{
return array(
sprintf(T("%s posted in %s."), "<i class='star icon-star'></i> ".name($item["fromMemberName"]), "<strong>".sanitizeHTML($item["data"]["title"])."</strong>"),
URL(postURL($item["postId"]))
);
}
// Format the postMember email.
public static function postMemberEmail($item, $member)
{
$content = ET::formatter()->init($item["data"]["content"])->format()->get();
$url = URL(conversationURL($item["data"]["conversationId"], $item["data"]["title"])."/unread", true);
return array(
sprintf(T("email.postMember.subject"), name($item["fromMemberName"], false)),
sprintf(T("email.postMember.body"), name($item["fromMemberName"]), sanitizeHTML($item["data"]["title"]), $content, "<a href='$url'>$url</a>")
);
}
}