Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
75.00% |
120 / 160 |
|
66.67% |
10 / 15 |
CRAP | |
0.00% |
0 / 1 |
board | |
75.00% |
120 / 160 |
|
66.67% |
10 / 15 |
146.56 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
add_to_queue | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
get_type | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
is_available | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
is_enabled_by_default | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
get_notified_users | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
6 | |||
load_notifications | |
71.62% |
53 / 74 |
|
0.00% |
0 / 1 |
27.25 | |||
notify | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
2 | |||
update_notification | |
92.31% |
12 / 13 |
|
0.00% |
0 / 1 |
7.02 | |||
mark_notifications | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
9 | |||
mark_notifications_by_parent | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
9 | |||
mark_notifications_by_id | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
20 | |||
delete_notifications | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
6 | |||
prune_notifications | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
purge_notifications | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | /** |
3 | * |
4 | * This file is part of the phpBB Forum Software package. |
5 | * |
6 | * @copyright (c) phpBB Limited <https://www.phpbb.com> |
7 | * @license GNU General Public License, version 2 (GPL-2.0) |
8 | * |
9 | * For full copyright and license information, please see |
10 | * the docs/CREDITS.txt file. |
11 | * |
12 | */ |
13 | |
14 | namespace phpbb\notification\method; |
15 | |
16 | /** |
17 | * In Board notification method class |
18 | * This class handles in board notifications. This method is enabled by default. |
19 | * |
20 | * @package notifications |
21 | */ |
22 | class board extends \phpbb\notification\method\base |
23 | { |
24 | /** @var \phpbb\user_loader */ |
25 | protected $user_loader; |
26 | |
27 | /** @var \phpbb\db\driver\driver_interface */ |
28 | protected $db; |
29 | |
30 | /** @var \phpbb\cache\driver\driver_interface */ |
31 | protected $cache; |
32 | |
33 | /** @var \phpbb\user */ |
34 | protected $user; |
35 | |
36 | /** @var \phpbb\config\config */ |
37 | protected $config; |
38 | |
39 | /** @var string */ |
40 | protected $notification_types_table; |
41 | |
42 | /** @var string */ |
43 | protected $notifications_table; |
44 | |
45 | /** |
46 | * Notification Method Board Constructor |
47 | * |
48 | * @param \phpbb\user_loader $user_loader |
49 | * @param \phpbb\db\driver\driver_interface $db |
50 | * @param \phpbb\cache\driver\driver_interface $cache |
51 | * @param \phpbb\user $user |
52 | * @param \phpbb\config\config $config |
53 | * @param string $notification_types_table |
54 | * @param string $notifications_table |
55 | */ |
56 | public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, \phpbb\user $user, \phpbb\config\config $config, $notification_types_table, $notifications_table) |
57 | { |
58 | $this->user_loader = $user_loader; |
59 | $this->db = $db; |
60 | $this->cache = $cache; |
61 | $this->user = $user; |
62 | $this->config = $config; |
63 | $this->notification_types_table = $notification_types_table; |
64 | $this->notifications_table = $notifications_table; |
65 | |
66 | } |
67 | |
68 | /** |
69 | * {@inheritdoc} |
70 | */ |
71 | public function add_to_queue(\phpbb\notification\type\type_interface $notification) |
72 | { |
73 | $this->queue[] = $notification; |
74 | } |
75 | |
76 | /** |
77 | * {@inheritdoc} |
78 | */ |
79 | public function get_type() |
80 | { |
81 | return 'notification.method.board'; |
82 | } |
83 | |
84 | /** |
85 | * {@inheritdoc} |
86 | */ |
87 | public function is_available() |
88 | { |
89 | return $this->config['allow_board_notifications']; |
90 | } |
91 | |
92 | /** |
93 | * {@inheritdoc} |
94 | */ |
95 | public function is_enabled_by_default() |
96 | { |
97 | return true; |
98 | } |
99 | |
100 | /** |
101 | * {@inheritdoc} |
102 | */ |
103 | public function get_notified_users($notification_type_id, array $options) |
104 | { |
105 | $notified_users = array(); |
106 | $sql = 'SELECT n.* |
107 | FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt |
108 | WHERE n.notification_type_id = ' . (int) $notification_type_id . |
109 | (isset($options['item_id']) ? ' AND n.item_id = ' . (int) $options['item_id'] : '') . |
110 | (isset($options['item_parent_id']) ? ' AND n.item_parent_id = ' . (int) $options['item_parent_id'] : '') . |
111 | (isset($options['user_id']) ? ' AND n.user_id = ' . (int) $options['user_id'] : '') . |
112 | (isset($options['read']) ? ' AND n.notification_read = ' . (int) $options['read'] : '') .' |
113 | AND nt.notification_type_id = n.notification_type_id |
114 | AND nt.notification_type_enabled = 1'; |
115 | $result = $this->db->sql_query($sql); |
116 | while ($row = $this->db->sql_fetchrow($result)) |
117 | { |
118 | $notified_users[$row['user_id']] = $row; |
119 | } |
120 | $this->db->sql_freeresult($result); |
121 | |
122 | return $notified_users; |
123 | } |
124 | |
125 | /** |
126 | * {@inheritdoc} |
127 | */ |
128 | public function load_notifications(array $options = array()) |
129 | { |
130 | // Merge default options |
131 | $options = array_merge(array( |
132 | 'notification_id' => false, |
133 | 'user_id' => $this->user->data['user_id'], |
134 | 'order_by' => 'notification_time', |
135 | 'order_dir' => 'DESC', |
136 | 'limit' => 0, |
137 | 'start' => 0, |
138 | 'all_unread' => false, |
139 | 'count_unread' => false, |
140 | 'count_total' => false, |
141 | ), $options); |
142 | |
143 | // If all_unread, count_unread must be true |
144 | $options['count_unread'] = ($options['all_unread']) ? true : $options['count_unread']; |
145 | |
146 | // Anonymous users and bots never receive notifications |
147 | if ($options['user_id'] == $this->user->data['user_id'] && ($this->user->data['user_id'] == ANONYMOUS || $this->user->data['user_type'] == USER_IGNORE)) |
148 | { |
149 | return array( |
150 | 'notifications' => array(), |
151 | 'unread_count' => 0, |
152 | 'total_count' => 0, |
153 | ); |
154 | } |
155 | |
156 | $notifications = $user_ids = array(); |
157 | $load_special = array(); |
158 | $total_count = $unread_count = 0; |
159 | |
160 | if ($options['count_unread']) |
161 | { |
162 | // Get the total number of unread notifications |
163 | $sql = 'SELECT COUNT(n.notification_id) AS unread_count |
164 | FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt |
165 | WHERE n.user_id = ' . (int) $options['user_id'] . ' |
166 | AND n.notification_read = 0 |
167 | AND nt.notification_type_id = n.notification_type_id |
168 | AND nt.notification_type_enabled = 1'; |
169 | $result = $this->db->sql_query($sql); |
170 | $unread_count = (int) $this->db->sql_fetchfield('unread_count'); |
171 | $this->db->sql_freeresult($result); |
172 | } |
173 | |
174 | if ($options['count_total']) |
175 | { |
176 | // Get the total number of notifications |
177 | $sql = 'SELECT COUNT(n.notification_id) AS total_count |
178 | FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt |
179 | WHERE n.user_id = ' . (int) $options['user_id'] . ' |
180 | AND nt.notification_type_id = n.notification_type_id |
181 | AND nt.notification_type_enabled = 1'; |
182 | $result = $this->db->sql_query($sql); |
183 | $total_count = (int) $this->db->sql_fetchfield('total_count'); |
184 | $this->db->sql_freeresult($result); |
185 | } |
186 | |
187 | if (!$options['count_total'] || $total_count) |
188 | { |
189 | $rowset = array(); |
190 | |
191 | // Get the main notifications |
192 | $sql = 'SELECT n.*, nt.notification_type_name |
193 | FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt |
194 | WHERE n.user_id = ' . (int) $options['user_id'] . |
195 | (($options['notification_id']) ? ((is_array($options['notification_id'])) ? ' AND ' . $this->db->sql_in_set('n.notification_id', $options['notification_id']) : ' AND n.notification_id = ' . (int) $options['notification_id']) : '') . ' |
196 | AND nt.notification_type_id = n.notification_type_id |
197 | AND nt.notification_type_enabled = 1 |
198 | ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']); |
199 | $result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']); |
200 | |
201 | while ($row = $this->db->sql_fetchrow($result)) |
202 | { |
203 | $rowset[$row['notification_id']] = $row; |
204 | } |
205 | $this->db->sql_freeresult($result); |
206 | |
207 | // Get all unread notifications |
208 | if ($unread_count && $options['all_unread'] && !empty($rowset)) |
209 | { |
210 | $sql = 'SELECT n.*, nt.notification_type_name |
211 | FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt |
212 | WHERE n.user_id = ' . (int) $options['user_id'] . ' |
213 | AND n.notification_read = 0 |
214 | AND ' . $this->db->sql_in_set('n.notification_id', array_keys($rowset), true) . ' |
215 | AND nt.notification_type_id = n.notification_type_id |
216 | AND nt.notification_type_enabled = 1 |
217 | ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']); |
218 | $result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']); |
219 | |
220 | while ($row = $this->db->sql_fetchrow($result)) |
221 | { |
222 | $rowset[$row['notification_id']] = $row; |
223 | } |
224 | $this->db->sql_freeresult($result); |
225 | } |
226 | |
227 | foreach ($rowset as $row) |
228 | { |
229 | $notification = $this->notification_manager->get_item_type_class($row['notification_type_name'], $row); |
230 | |
231 | // Array of user_ids to query all at once |
232 | $user_ids = array_merge($user_ids, $notification->users_to_query()); |
233 | |
234 | // Some notification types also require querying additional tables themselves |
235 | if (!isset($load_special[$row['notification_type_name']])) |
236 | { |
237 | $load_special[$row['notification_type_name']] = array(); |
238 | } |
239 | $load_special[$row['notification_type_name']] = array_merge($load_special[$row['notification_type_name']], $notification->get_load_special()); |
240 | |
241 | $notifications[$row['notification_id']] = $notification; |
242 | } |
243 | |
244 | $this->user_loader->load_users($user_ids); |
245 | |
246 | // Allow each type to load its own special items |
247 | foreach ($load_special as $item_type => $data) |
248 | { |
249 | $item_class = $this->notification_manager->get_item_type_class($item_type); |
250 | |
251 | $item_class->load_special($data, $notifications); |
252 | } |
253 | } |
254 | |
255 | return array( |
256 | 'notifications' => $notifications, |
257 | 'unread_count' => $unread_count, |
258 | 'total_count' => $total_count, |
259 | ); |
260 | } |
261 | |
262 | /** |
263 | * {@inheritdoc} |
264 | */ |
265 | public function notify() |
266 | { |
267 | $insert_buffer = new \phpbb\db\sql_insert_buffer($this->db, $this->notifications_table); |
268 | |
269 | /** @var \phpbb\notification\type\type_interface $notification */ |
270 | foreach ($this->queue as $notification) |
271 | { |
272 | $data = $notification->get_insert_array(); |
273 | $insert_buffer->insert($data); |
274 | } |
275 | |
276 | $insert_buffer->flush(); |
277 | |
278 | // We're done, empty the queue |
279 | $this->empty_queue(); |
280 | } |
281 | |
282 | /** |
283 | * {@inheritdoc} |
284 | */ |
285 | public function update_notification($notification, array $data, array $options) |
286 | { |
287 | // Allow the notifications class to over-ride the update_notifications functionality |
288 | if (method_exists($notification, 'update_notifications')) |
289 | { |
290 | // Return False to over-ride the rest of the update |
291 | if ($notification->update_notifications($data) === false) |
292 | { |
293 | return; |
294 | } |
295 | } |
296 | |
297 | $notification_type_id = $this->notification_manager->get_notification_type_id($notification->get_type()); |
298 | $update_array = $notification->create_update_array($data); |
299 | |
300 | $sql = 'UPDATE ' . $this->notifications_table . ' |
301 | SET ' . $this->db->sql_build_array('UPDATE', $update_array) . ' |
302 | WHERE notification_type_id = ' . (int) $notification_type_id . |
303 | (isset($options['item_id']) ? ' AND item_id = ' . (int) $options['item_id'] : '') . |
304 | (isset($options['item_parent_id']) ? ' AND item_parent_id = ' . (int) $options['item_parent_id'] : '') . |
305 | (isset($options['user_id']) ? ' AND user_id = ' . (int) $options['user_id'] : '') . |
306 | (isset($options['read']) ? ' AND notification_read = ' . (int) $options['read'] : ''); |
307 | $this->db->sql_query($sql); |
308 | } |
309 | |
310 | /** |
311 | * {@inheritdoc} |
312 | */ |
313 | public function mark_notifications($notification_type_id, $item_id, $user_id, $time = false, $mark_read = true) |
314 | { |
315 | $time = ($time !== false) ? $time : time(); |
316 | |
317 | $sql = 'UPDATE ' . $this->notifications_table . ' |
318 | SET notification_read = ' . ($mark_read ? 1 : 0) . ' |
319 | WHERE notification_time <= ' . (int) $time . |
320 | (($notification_type_id !== false) ? ' AND ' . |
321 | (is_array($notification_type_id) ? $this->db->sql_in_set('notification_type_id', $notification_type_id) : 'notification_type_id = ' . $notification_type_id) : '') . |
322 | (($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '') . |
323 | (($item_id !== false) ? ' AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) : ''); |
324 | $this->db->sql_query($sql); |
325 | } |
326 | |
327 | /** |
328 | * {@inheritdoc} |
329 | */ |
330 | public function mark_notifications_by_parent($notification_type_id, $item_parent_id, $user_id, $time = false, $mark_read = true) |
331 | { |
332 | $time = ($time !== false) ? $time : time(); |
333 | |
334 | $sql = 'UPDATE ' . $this->notifications_table . ' |
335 | SET notification_read = ' . ($mark_read ? 1 : 0) . ' |
336 | WHERE notification_time <= ' . (int) $time . |
337 | (($notification_type_id !== false) ? ' AND ' . |
338 | (is_array($notification_type_id) ? $this->db->sql_in_set('notification_type_id', $notification_type_id) : 'notification_type_id = ' . $notification_type_id) : '') . |
339 | (($item_parent_id !== false) ? ' AND ' . (is_array($item_parent_id) ? $this->db->sql_in_set('item_parent_id', $item_parent_id, false, true) : 'item_parent_id = ' . (int) $item_parent_id) : '') . |
340 | (($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : ''); |
341 | $this->db->sql_query($sql); |
342 | } |
343 | |
344 | /** |
345 | * {@inheritdoc} |
346 | */ |
347 | public function mark_notifications_by_id($notification_id, $time = false, $mark_read = true) |
348 | { |
349 | $time = ($time !== false) ? $time : time(); |
350 | |
351 | $sql = 'UPDATE ' . $this->notifications_table . ' |
352 | SET notification_read = ' . ($mark_read ? 1 : 0) . ' |
353 | WHERE notification_time <= ' . (int) $time . ' |
354 | AND ' . ((is_array($notification_id)) ? $this->db->sql_in_set('notification_id', $notification_id) : 'notification_id = ' . (int) $notification_id); |
355 | $this->db->sql_query($sql); |
356 | } |
357 | |
358 | /** |
359 | * {@inheritdoc} |
360 | */ |
361 | public function delete_notifications($notification_type_id, $item_id, $parent_id = false, $user_id = false) |
362 | { |
363 | $sql = 'DELETE FROM ' . $this->notifications_table . ' |
364 | WHERE notification_type_id = ' . (int) $notification_type_id . ' |
365 | AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) . |
366 | (($parent_id !== false) ? ' AND ' . ((is_array($parent_id) ? $this->db->sql_in_set('item_parent_id', $parent_id) : 'item_parent_id = ' . (int) $parent_id)) : '') . |
367 | (($user_id !== false) ? ' AND ' . ((is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id)) : ''); |
368 | $this->db->sql_query($sql); |
369 | } |
370 | |
371 | /** |
372 | * {@inheritdoc} |
373 | */ |
374 | public function prune_notifications($timestamp, $only_read = true) |
375 | { |
376 | $sql = 'DELETE FROM ' . $this->notifications_table . ' |
377 | WHERE notification_time < ' . (int) $timestamp . |
378 | (($only_read) ? ' AND notification_read = 1' : ''); |
379 | $this->db->sql_query($sql); |
380 | |
381 | $this->config->set('read_notification_last_gc', time(), false); |
382 | } |
383 | |
384 | /** |
385 | * {@inheritdoc} |
386 | */ |
387 | public function purge_notifications($notification_type_id) |
388 | { |
389 | $sql = 'DELETE FROM ' . $this->notifications_table . ' |
390 | WHERE notification_type_id = ' . (int) $notification_type_id; |
391 | $this->db->sql_query($sql); |
392 | |
393 | $sql = 'DELETE FROM ' . $this->notification_types_table . ' |
394 | WHERE notification_type_id = ' . (int) $notification_type_id; |
395 | $this->db->sql_query($sql); |
396 | |
397 | $this->cache->destroy('sql', $this->notification_types_table); |
398 | } |
399 | } |