r859: - Adding some notification implementation to the notice_*() functions
[bugdar.git] / includes / class_notification.php
1 <?php
2 /*=====================================================================*\
3 || ###################################################################
4 || # Bugdar [#]version[#]
5 || # Copyright ©2002-[#]year[#] Iris Studios, Inc.
6 || #
7 || # This program is free software; you can redistribute it and/or modify
8 || # it under the terms of the GNU General Public License as published by
9 || # the Free Software Foundation; version [#]gpl[#] of the License.
10 || #
11 || # This program is distributed in the hope that it will be useful, but
12 || # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 || # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 || # more details.
15 || #
16 || # You should have received a copy of the GNU General Public License along
17 || # with this program; if not, write to the Free Software Foundation, Inc.,
18 || # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 || ###################################################################
20 \*=====================================================================*/
21
22 /**
23 * Notification Center
24 *
25 * This class determines which emails need to be sent out based on user
26 * options and bug changes, and then it sends said emails.
27 *
28 * @author Iris Studios, Inc.
29 * @copyright Copyright ©2002 - [#]year[#], Iris Studios, Inc.
30 * @version $Revision$
31 * @package Bugdar
32 *
33 */
34 class NotificationCenter
35 {
36 /**
37 * Bug information
38 * @var array
39 * @access private
40 */
41 var $bug = array();
42
43 /**
44 * Global bugsys registry
45 * @var object
46 * @access private
47 */
48 var $registry = null;
49
50 /**
51 * Role list: a list of user IDs with their relations to the bug
52 * @var array
53 * @access private
54 */
55 var $roles = array(
56 '-notapplicable-' => array(),
57 'reporter' => array(),
58 'assignee' => array(),
59 'favourite' => array(),
60 'voter' => array(),
61 'commenter' => array()
62 );
63
64 /**
65 * User cache list
66 * @var array
67 * @access private
68 */
69 var $users = array();
70
71 /**
72 * A list of notices per-user that are combined together in NotificationCenter::finalize()
73 * @var array
74 * @access private
75 */
76 var $notices = array();
77
78 // ###################################################################
79 /**
80 * Constructor: set database objects
81 *
82 * @access public
83 */
84 function __construct()
85 {
86 global $bugsys;
87
88 $this->registry =& $bugsys;
89 }
90
91 // ###################################################################
92 /**
93 * (PHP 4) Constructor
94 *
95 * @access public
96 */
97 function NotificationCenter()
98 {
99 $this->__construct();
100 }
101
102 // ###################################################################
103 /**
104 * Fetches all the users who could be related to the bug and sticks
105 * their information into an array.
106 *
107 * @access private
108 */
109 function fetch_user_cache()
110 {
111 $favourites = $this->registry->db->query("SELECT userid FROM " . TABLE_PREFIX . "favourite WHERE bugid = " . $this->registry->clean($this->bug['bugid'], TYPE_UINT));
112 while ($fav = $this->registry->db->fetch_array($favourites))
113 {
114 $this->roles['favourite']["$fav[userid]"] = $fav['userid'];
115 }
116
117 $voters = $this->registry->db->query_first("SELECT userids FROM " . TABLE_PREFIX . "vote WHERE bugid = " . $this->registry->clean($this->bug['bugid'], TYPE_UINT));
118 $this->roles['voter'] = explode(',', $voters['userids']);
119
120 $commenters = $this->registry->db->query("SELECT userid FROM " . TABLE_PREFIX . "comment WHERE bugid = " . $this->registry->clean($this->bug['bugid'], TYPE_UINT));
121 while ($comment = $this->registry->db->fetch_array($commenters))
122 {
123 $this->roles['commenter']["$comment[userid]"] = $comment['userid'];
124 }
125
126 $masterids = array_merge($this->roles['-notapplicable-'], $this->roles['reporter'], $this->roles['assignee'], $this->roles['favourite'], $this->roles['voter'], $this->roles['commenter']);
127 $masterids = array_unique($masterids);
128
129 $userinfo = $this->registry->db->query("
130 SELECT user.*, useremail.*
131 FROM " . TABLE_PREFIX . "useremail AS useremail
132 LEFT JOIN " . TABLE_PREFIX . "user AS user
133 ON (user.userid = useremail.userid)
134 WHERE useremail.userid IN (" . implode(',', $masterids) . ")
135 ");
136 while ($user = $this->registry->db->fetch_array($userinfo))
137 {
138 if (!is_array($this->users["$user[userid]"]))
139 {
140 $this->users["$user[userid]"] = $user;
141 unset($this->users["$user[userid]"]['mask'], $this->users["$user[userid]"]['relation']);
142 }
143 $this->users["$user[userid]"]['options']["$user[relation]"] = $user['mask'];
144 }
145 }
146
147 // ###################################################################
148 /**
149 * Sends the appropriate emails for changes to bugs. This function
150 * works a lot like the Logging class by taking BugAPI->objdata and
151 * BugAPI->values and then comparing the two arries and sending emails
152 * with the differences.
153 *
154 * @access public
155 *
156 * @param array Original data (BugAPI->objdata)
157 * @param array Modified data (BugAPI->values)
158 */
159 function send_bug_changes_notice($original, $modified)
160 {
161 $this->bug = $modified;
162
163 $this->roles['-notapplicable-'] = array($original['assignedto'], $modified['assignedto']);
164 $this->roles['reporter'] = array($original['userid']);
165 $this->roles['assignee'] = array($modified['assignedto']);
166
167 $this->fetch_user_cache();
168
169 if ($original['assignedto'] != $modified['assignedto'])
170 {
171 if ($original['assignedto'] != '')
172 {
173 $this->notice_no_longer_assigned($original['assignedto']);
174 }
175 if ($modified['assignedto'] != '')
176 {
177 $this->notice_now_assigned($modified['assignedto']);
178 }
179 }
180
181 if ($original['status'] != $modified['status'])
182 {
183 $this->notice_status_change($original['status'], $modified['status']);
184 }
185 if ($original['resolution'] != $modified['resoultion'])
186 {
187 $this->notice_resolution_change($original['resolution'], $modified['resolution']);
188 }
189
190 if ($original['duplicates'] != $modified['duplicates'])
191 {
192 $this->notice_duplicates_change($original['duplicates'], $modified['duplicates']);
193 }
194 }
195
196 // ###################################################################
197 /**
198 * Sends an email to the specified user ID that they are no longer the
199 * person assigned to the bug.
200 *
201 * @access private
202 *
203 * @param integer User ID to send to
204 */
205 function notice_no_longer_assigned($userid)
206 {
207 if ($this->users["$userid"]['options'][0] & $this->registry->emailoptions['notifications']['assignedto'] AND in_array($userid, $this->roles['-notapplicable-']))
208 {
209 $this->notices["$userid"][] = sprintf(
210 $this->registry->lang->string('You are no longer assigned to this bug, per %1$s\'s changes.'),
211
212 construct_user_display($this->registry->userinfo, false)
213 );
214 }
215 }
216
217 // ###################################################################
218 /**
219 * Informs the user that they have been made the assignee of the bug.
220 *
221 * @access private
222 *
223 * @param integer User ID
224 */
225 function notice_now_assigned($userid)
226 {
227 if ($this->users["$userid"]['options'][0] & $this->registry->emailoptions['notifications']['assignedto'] AND in_array($userid, $this->roles['-notapplicable-']))
228 {
229 $this->notices["$userid"][] = sprintf(
230 $this->registry->lang->string('You have been assigned to this bug by %1$s.'),
231
232 construct_user_display($this->registry->userinfo, false)
233 );
234 }
235 }
236
237 // ###################################################################
238 /**
239 * Sends a message to inform users that the status has changed.
240 *
241 * @access private
242 *
243 * @param integer Old status
244 * @param integer New status
245 */
246 function notice_status_change($old, $new)
247 {
248 $userlist = $this->fetch_users_with_on_bit('statusresolve');
249 foreach ($userlist AS $userid => $user)
250 {
251 $this->notices["$user[userid]"][] = sprintf(
252 $this->registry->lang->string('The status field has changed from "%1$s" to "%2$s".'),
253
254 $this->registry->datastore['status']["$old"]['status'],
255 $this->registry->datastore['status']["$new"]['status']
256 );
257 }
258 }
259
260 // ###################################################################
261 /**
262 * Sends an email to inform users that the resolution has changed.
263 *
264 * @access private
265 *
266 * @param integer Old resolution
267 * @param integer New resolution
268 */
269 function notice_resolution_change($old, $new)
270 {
271 $userlist = $this->fetch_users_with_on_bit('statusresolve');
272 foreach ($userlist AS $userid => $user)
273 {
274 $this->notices["$user[userid]"][] = sprintf(
275 $this->registry->lang->string('The resolution field has changed from "%1$s" to "%2$s".'),
276
277 $this->registry->datastore['resolution']["$old"]['resolution'],
278 $this->registry->datastore['resolution']["$new"]['resolution']
279 );
280 }
281 }
282
283 // ###################################################################
284 /**
285 * Informs users that the duplicates list has changed.
286 *
287 * @access private
288 *
289 * @param string Old duplicates list
290 * @param string New duplicates list
291 */
292 function notice_duplicates_change($old, $new)
293 {
294
295 }
296
297 // ###################################################################
298 /**
299 * Sends the appropriate users information about a new comment being
300 * posted to the bug report.
301 *
302 * @access public
303 *
304 * @param array CommentAPI->values array
305 */
306 function send_new_comment_notice($comment)
307 {
308
309 }
310
311 // ###################################################################
312 /**
313 * Generates an array of users who have a given email notification flag
314 * turned on in their bitfields.
315 *
316 * @access private
317 *
318 * @param string Notification bitfield name
319 *
320 * @return array Array of users and their data
321 */
322 function fetch_users_with_on_bit($bitname)
323 {
324 $idlist = array();
325
326 foreach ($this->users AS $user)
327 {
328 foreach ($this->registry->emailoptions['relations'] AS $name => $bit)
329 {
330 if (in_array($user['userid'], $this->roles["$name"]) AND $user['options']["$bit"] & $this->registry->emailoptions['notifications']["$bitname"])
331 {
332 $idlist[] = $user['userid'];
333 }
334 }
335 }
336
337 $masters = array_unique($idlist);
338
339 $return = array();
340 foreach ($masters AS $userid)
341 {
342 $return["$userid"] =& $this->users["$userid"];
343 }
344
345 return $return;
346 }
347 }
348
349 /*=====================================================================*\
350 || ###################################################################
351 || # $HeadURL$
352 || # $Id$
353 || ###################################################################
354 \*=====================================================================*/
355 ?>