Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
manager.php
001 <?php
002 /**
003 *
004 * This file is part of the phpBB Forum Software package.
005 *
006 * @copyright (c) phpBB Limited <https://www.phpbb.com>
007 * @license GNU General Public License, version 2 (GPL-2.0)
008 *
009 * For full copyright and license information, please see
010 * the docs/CREDITS.txt file.
011 *
012 */
013
014 namespace phpbb\notification;
015
016 use Symfony\Component\DependencyInjection\ContainerInterface;
017
018 /**
019 * Notifications service class
020 */
021 class manager
022 {
023 /** @var array */
024 protected $notification_types;
025
026 /** @var array */
027 protected $subscription_types;
028
029 /** @var method\method_interface[] */
030 protected $notification_methods;
031
032 /** @var ContainerInterface */
033 protected $phpbb_container;
034
035 /** @var \phpbb\user_loader */
036 protected $user_loader;
037
038 /** @var \phpbb\event\dispatcher_interface */
039 protected $phpbb_dispatcher;
040
041 /** @var \phpbb\db\driver\driver_interface */
042 protected $db;
043
044 /** @var \phpbb\cache\service */
045 protected $cache;
046
047 /** @var \phpbb\language\language */
048 protected $language;
049
050 /** @var \phpbb\user */
051 protected $user;
052
053 /** @var string */
054 protected $notification_types_table;
055
056 /** @var string */
057 protected $user_notifications_table;
058
059 /**
060 * Notification Constructor
061 *
062 * @param array $notification_types
063 * @param array $notification_methods
064 * @param ContainerInterface $phpbb_container
065 * @param \phpbb\user_loader $user_loader
066 * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher
067 * @param \phpbb\db\driver\driver_interface $db
068 * @param \phpbb\cache\service $cache
069 * @param \phpbb\language\language $language
070 * @param \phpbb\user $user
071 * @param string $notification_types_table
072 * @param string $user_notifications_table
073 *
074 * @return \phpbb\notification\manager
075 */
076 public function __construct($notification_types, $notification_methods, ContainerInterface $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\event\dispatcher_interface $phpbb_dispatcher, \phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\language\language $language, \phpbb\user $user, $notification_types_table, $user_notifications_table)
077 {
078 $this->notification_types = $notification_types;
079 $this->notification_methods = $notification_methods;
080 $this->phpbb_container = $phpbb_container;
081
082 $this->user_loader = $user_loader;
083 $this->phpbb_dispatcher = $phpbb_dispatcher;
084 $this->db = $db;
085 $this->cache = $cache;
086 $this->language = $language;
087 $this->user = $user;
088
089 $this->notification_types_table = $notification_types_table;
090 $this->user_notifications_table = $user_notifications_table;
091 }
092
093 /**
094 * Load the user's notifications for a given method
095 *
096 * @param string $method_name
097 * @param array $options Optional options to control what notifications are loaded
098 * notification_id Notification id to load (or array of notification ids)
099 * user_id User id to load notifications for (Default: $user->data['user_id'])
100 * order_by Order by (Default: notification_time)
101 * order_dir Order direction (Default: DESC)
102 * limit Number of notifications to load (Default: 5)
103 * start Notifications offset (Default: 0)
104 * all_unread Load all unread notifications? If set to true, count_unread is set to true (Default: false)
105 * count_unread Count all unread notifications? (Default: false)
106 * count_total Count all notifications? (Default: false)
107 * @return array Array of information based on the request with keys:
108 * 'notifications' array of notification type objects
109 * 'unread_count' number of unread notifications the user has if count_unread is true in the options
110 * 'total_count' number of notifications the user has if count_total is true in the options
111 * @throws \phpbb\notification\exception when the method doesn't refer to a class extending \phpbb\notification\method\method_interface
112 */
113 public function load_notifications($method_name, array $options = array())
114 {
115 $method = $this->get_method_class($method_name);
116
117 if (! $method instanceof \phpbb\notification\method\method_interface)
118 {
119 throw new \phpbb\notification\exception($this->language->lang('NOTIFICATION_METHOD_INVALID', $method_name));
120 }
121 else if ($method->is_available())
122 {
123 return $method->load_notifications($options);
124 }
125 else
126 {
127 return array(
128 'notifications' => array(),
129 'unread_count' => 0,
130 'total_count' => 0,
131 );
132 }
133 }
134
135 /**
136 * Mark notifications read or unread for all available methods
137 *
138 * @param bool|string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types). False to mark read for all item types
139 * @param bool|int|array $item_id Item id or array of item ids. False to mark read for all item ids
140 * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
141 * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
142 *
143 * @deprecated since 3.2
144 */
145 public function mark_notifications_read($notification_type_name, $item_id, $user_id, $time = false)
146 {
147 $this->mark_notifications($notification_type_name, $item_id, $user_id, $time);
148 }
149
150 /**
151 * Mark notifications read or unread for all available methods
152 *
153 * @param bool|string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types). False to mark read for all item types
154 * @param bool|int|array $item_id Item id or array of item ids. False to mark read for all item ids
155 * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
156 * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
157 * @param bool $mark_read Define if the notification as to be set to True or False. (Default: True)
158 */
159 public function mark_notifications($notification_type_name, $item_id, $user_id, $time = false, $mark_read = true)
160 {
161 if (is_array($notification_type_name))
162 {
163 $notification_type_id = $this->get_notification_type_ids($notification_type_name);
164 }
165 else if ($notification_type_name !== false)
166 {
167 $notification_type_id = $this->get_notification_type_id($notification_type_name);
168 }
169 else
170 {
171 $notification_type_id = false;
172 }
173
174 /** @var method\method_interface $method */
175 foreach ($this->get_available_subscription_methods() as $method)
176 {
177 $method->mark_notifications($notification_type_id, $item_id, $user_id, $time, $mark_read);
178 }
179 }
180
181 /**
182 * Mark notifications read or unread from a parent identifier for all available methods
183 *
184 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
185 * @param bool|int|array $item_parent_id Item parent id or array of item parent ids. False to mark read for all item parent ids
186 * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
187 * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
188 *
189 * @deprecated since 3.2
190 */
191 public function mark_notifications_read_by_parent($notification_type_name, $item_parent_id, $user_id, $time = false)
192 {
193 $this->mark_notifications_by_parent($notification_type_name, $item_parent_id, $user_id, $time);
194 }
195
196 /**
197 * Mark notifications read or unread from a parent identifier for all available methods
198 *
199 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
200 * @param bool|int|array $item_parent_id Item parent id or array of item parent ids. False to mark read for all item parent ids
201 * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
202 * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
203 * @param bool $mark_read Define if the notification as to be set to True or False. (Default: True)
204 */
205 public function mark_notifications_by_parent($notification_type_name, $item_parent_id, $user_id, $time = false, $mark_read = true)
206 {
207 if (is_array($notification_type_name))
208 {
209 $notification_type_id = $this->get_notification_type_ids($notification_type_name);
210 }
211 else
212 {
213 $notification_type_id = $this->get_notification_type_id($notification_type_name);
214 }
215
216 /** @var method\method_interface $method */
217 foreach ($this->get_available_subscription_methods() as $method)
218 {
219 $method->mark_notifications_by_parent($notification_type_id, $item_parent_id, $user_id, $time, $mark_read);
220 }
221 }
222
223 /**
224 * Mark notifications read or unread for a given method
225 *
226 * @param string $method_name
227 * @param int|array $notification_id Notification id or array of notification ids.
228 * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
229 * @param bool $mark_read Define if the notification as to be set to True or False. (Default: True)
230 */
231 public function mark_notifications_by_id($method_name, $notification_id, $time = false, $mark_read = true)
232 {
233 $method = $this->get_method_class($method_name);
234
235 if ($method instanceof \phpbb\notification\method\method_interface && $method->is_available())
236 {
237 $method->mark_notifications_by_id($notification_id, $time, $mark_read);
238 }
239 }
240
241 /**
242 * Add a notification
243 *
244 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
245 * Note: If you send an array of types, any user who could receive multiple notifications from this single item will only receive
246 * a single notification. If they MUST receive multiple notifications, call this function multiple times instead of sending an array
247 * @param array $data Data specific for this type that will be inserted
248 * @param array $options Optional options to control what notifications are loaded
249 * ignore_users array of data to specify which users should not receive certain types of notifications
250 * @return array Information about what users were notified and how they were notified
251 */
252 public function add_notifications($notification_type_name, $data, array $options = array())
253 {
254 $options = array_merge(array(
255 'ignore_users' => array(),
256 ), $options);
257
258 if (is_array($notification_type_name))
259 {
260 $notified_users = array();
261 $temp_options = $options;
262
263 foreach ($notification_type_name as $type)
264 {
265 $temp_options['ignore_users'] = $options['ignore_users'] + $notified_users;
266 $notified_users += $this->add_notifications($type, $data, $temp_options);
267 }
268
269 return $notified_users;
270 }
271
272 // find out which users want to receive this type of notification
273 $notify_users = $this->get_item_type_class($notification_type_name)->find_users_for_notification($data, $options);
274
275 /**
276 * Allow filtering the notify_users array for a notification that is about to be sent.
277 * Here, $notify_users is already filtered by f_read and the ignored list included in the options variable
278 *
279 * @event core.notification_manager_add_notifications
280 * @var string notification_type_name The forum id from where the topic belongs
281 * @var array data Data specific for the notification_type_name used will be inserted
282 * @var array notify_users The array of userid that are going to be notified for this notification. Set to array() to cancel.
283 * @var array options The options that were used when this method was called (read only)
284 *
285 * @since 3.1.3-RC1
286 */
287 $vars = array(
288 'notification_type_name',
289 'data',
290 'notify_users',
291 'options',
292 );
293 extract($this->phpbb_dispatcher->trigger_event('core.notification_manager_add_notifications', compact($vars)));
294
295 $this->add_notifications_for_users($notification_type_name, $data, $notify_users);
296
297 return $notify_users;
298 }
299
300 /**
301 * Add a notification for specific users
302 *
303 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
304 * @param array $data Data specific for this type that will be inserted
305 * @param array $notify_users User list to notify
306 */
307 public function add_notifications_for_users($notification_type_name, $data, $notify_users)
308 {
309 if (is_array($notification_type_name))
310 {
311 foreach ($notification_type_name as $type)
312 {
313 $this->add_notifications_for_users($type, $data, $notify_users);
314 }
315
316 return;
317 }
318
319 $notification_type_id = $this->get_notification_type_id($notification_type_name);
320
321 $item_id = $this->get_item_type_class($notification_type_name)->get_item_id($data);
322
323 $user_ids = array();
324 $notification_methods = array();
325
326 // Never send notifications to the anonymous user!
327 unset($notify_users[ANONYMOUS]);
328
329 // Make sure not to send new notifications to users who've already been notified about this item
330 // This may happen when an item was added, but now new users are able to see the item
331 // We remove each user which was already notified by at least one method.
332 /** @var method\method_interface $method */
333 foreach ($this->get_subscription_methods_instances() as $method)
334 {
335 $notified_users = $method->get_notified_users($notification_type_id, array('item_id' => $item_id));
336 foreach ($notified_users as $user => $notifications)
337 {
338 unset($notify_users[$user]);
339 }
340 }
341
342 if (!sizeof($notify_users))
343 {
344 return;
345 }
346
347 // Allow notifications to perform actions before creating the insert array (such as run a query to cache some data needed for all notifications)
348 $notification = $this->get_item_type_class($notification_type_name);
349 $pre_create_data = $notification->pre_create_insert_array($data, $notify_users);
350 unset($notification);
351
352 // Go through each user so we can insert a row in the DB and then notify them by their desired means
353 foreach ($notify_users as $user => $methods)
354 {
355 $notification = $this->get_item_type_class($notification_type_name);
356
357 $notification->user_id = (int) $user;
358
359 // Generate the insert_array
360 $notification->create_insert_array($data, $pre_create_data);
361
362 // Users are needed to send notifications
363 $user_ids = array_merge($user_ids, $notification->users_to_query());
364
365 foreach ($methods as $method)
366 {
367 // setup the notification methods and add the notification to the queue
368 if (!isset($notification_methods[$method]))
369 {
370 $notification_methods[$method] = $this->get_method_class($method);
371 }
372
373 $notification_methods[$method]->add_to_queue($notification);
374 }
375 }
376
377 // We need to load all of the users to send notifications
378 $this->user_loader->load_users($user_ids);
379
380 // run the queue for each method to send notifications
381 foreach ($notification_methods as $method)
382 {
383 $method->notify();
384 }
385 }
386
387 /**
388 * Update notification
389 *
390 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
391 * @param array $data Data specific for this type that will be updated
392 * @param array $options
393 */
394 public function update_notifications($notification_type_name, array $data, array $options = array())
395 {
396 if (is_array($notification_type_name))
397 {
398 foreach ($notification_type_name as $type)
399 {
400 $this->update_notifications($type, $data);
401 }
402
403 return;
404 }
405
406 $this->update_notification($this->get_item_type_class($notification_type_name), $data, $options);
407 }
408
409 /**
410 * Update a notification
411 *
412 * @param \phpbb\notification\type\type_interface $notification The notification
413 * @param array $data Data specific for this type that will be updated
414 * @param array $options
415 */
416 public function update_notification(\phpbb\notification\type\type_interface $notification, array $data, array $options = array())
417 {
418 if (empty($options))
419 {
420 $options['item_id'] = $notification->get_item_id($data);
421 }
422
423 /** @var method\method_interface $method */
424 foreach ($this->get_available_subscription_methods() as $method)
425 {
426 $method->update_notification($notification, $data, $options);
427 }
428 }
429
430 /**
431 * Delete a notification
432 *
433 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $item_id is identical for the specified types)
434 * @param int|array $item_id Identifier within the type (or array of ids)
435 * @param mixed $parent_id Parent identifier within the type (or array of ids), used in combination with item_id if specified (Default: false; not checked)
436 * @param mixed $user_id User id (Default: false; not checked)
437 */
438 public function delete_notifications($notification_type_name, $item_id, $parent_id = false, $user_id = false)
439 {
440 if (is_array($notification_type_name))
441 {
442 foreach ($notification_type_name as $type)
443 {
444 $this->delete_notifications($type, $item_id, $parent_id, $user_id);
445 }
446
447 return;
448 }
449
450 $notification_type_id = $this->get_notification_type_id($notification_type_name);
451
452 /** @var method\method_interface $method */
453 foreach ($this->get_available_subscription_methods() as $method)
454 {
455 $method->delete_notifications($notification_type_id, $item_id, $parent_id, $user_id);
456 }
457 }
458
459 /**
460 * Get all of the subscription types
461 *
462 * @return array Array of item types
463 */
464 public function get_subscription_types()
465 {
466 if ($this->subscription_types === null)
467 {
468 $this->subscription_types = array();
469
470 foreach ($this->notification_types as $type_name => $data)
471 {
472 /** @var type\base $type */
473 $type = $this->get_item_type_class($type_name);
474
475 if ($type instanceof \phpbb\notification\type\type_interface && $type->is_available())
476 {
477 $options = array_merge(array(
478 'id' => $type->get_type(),
479 'lang' => 'NOTIFICATION_TYPE_' . strtoupper($type->get_type()),
480 'group' => 'NOTIFICATION_GROUP_MISCELLANEOUS',
481 ), (($type::$notification_option !== false) ? $type::$notification_option : array()));
482
483 $this->subscription_types[$options['group']][$options['id']] = $options;
484 }
485 }
486
487 // Move Miscellaneous to the very last section
488 if (isset($this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS']))
489 {
490 $miscellaneous = $this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS'];
491 unset($this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS']);
492 $this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS'] = $miscellaneous;
493 }
494 }
495
496 return $this->subscription_types;
497 }
498
499 /**
500 * Get all of the subscription methods
501 *
502 * @return array Array of methods
503 */
504 public function get_subscription_methods()
505 {
506 $subscription_methods = array();
507
508 /** @var method\method_interface $method */
509 foreach ($this->get_available_subscription_methods() as $method_name => $method)
510 {
511 $subscription_methods[$method_name] = array(
512 'id' => $method->get_type(),
513 'lang' => str_replace('.', '_', strtoupper($method->get_type())),
514 );
515 }
516
517 return $subscription_methods;
518 }
519
520 /**
521 * Get all of the subscription methods
522 *
523 * @return array Array of method's instances
524 */
525 private function get_subscription_methods_instances()
526 {
527 $subscription_methods = array();
528
529 foreach ($this->notification_methods as $method_name => $data)
530 {
531 $method = $this->get_method_class($method_name);
532
533 if ($method instanceof \phpbb\notification\method\method_interface)
534 {
535 $subscription_methods[$method_name] = $method;
536 }
537 }
538
539 return $subscription_methods;
540 }
541
542 /**
543 * Get all of the available subscription methods
544 *
545 * @return array Array of method's instances
546 */
547 private function get_available_subscription_methods()
548 {
549 $subscription_methods = array();
550
551 /** @var method\method_interface $method */
552 foreach ($this->get_subscription_methods_instances() as $method_name => $method)
553 {
554 if ($method->is_available())
555 {
556 $subscription_methods[$method_name] = $method;
557 }
558 }
559
560 return $subscription_methods;
561 }
562
563
564 /**
565 * Get user's notification data
566 *
567 * @param int $user_id The user_id of the user to get the notifications for
568 *
569 * @return array User's notification
570 */
571 protected function get_user_notifications($user_id)
572 {
573 $sql = 'SELECT method, notify, item_type
574 FROM ' . $this->user_notifications_table . '
575 WHERE user_id = ' . (int) $user_id . '
576 AND item_id = 0';
577
578 $result = $this->db->sql_query($sql);
579 $user_notifications = array();
580
581 while ($row = $this->db->sql_fetchrow($result))
582 {
583 $user_notifications[$row['item_type']][] = $row;
584 }
585
586 $this->db->sql_freeresult($result);
587
588 return $user_notifications;
589 }
590
591 /**
592 * Get global subscriptions (item_id = 0)
593 *
594 * @param bool|int $user_id The user_id to add the subscription for (bool false for current user)
595 *
596 * @return array Subscriptions
597 */
598 public function get_global_subscriptions($user_id = false)
599 {
600 $user_id = $user_id ?: $this->user->data['user_id'];
601
602 $subscriptions = array();
603 $default_methods = $this->get_default_methods();
604
605 $user_notifications = $this->get_user_notifications($user_id);
606
607 foreach ($this->get_subscription_types() as $types)
608 {
609 foreach ($types as $id => $type)
610 {
611 $type_subscriptions = $default_methods;
612 if (!empty($user_notifications[$id]))
613 {
614 foreach ($user_notifications[$id] as $user_notification)
615 {
616 $key = array_search($user_notification['method'], $type_subscriptions, true);
617 if (!$user_notification['notify'])
618 {
619 if ($key !== false)
620 {
621 unset($type_subscriptions[$key]);
622 }
623
624 continue;
625 }
626 else if ($key === false)
627 {
628 $type_subscriptions[] = $user_notification['method'];
629 }
630 }
631 }
632
633 if (!empty($type_subscriptions))
634 {
635 $subscriptions[$id] = $type_subscriptions;
636 }
637 }
638 }
639
640 return $subscriptions;
641 }
642
643 /**
644 * Add a subscription
645 *
646 * @param string $item_type Type identifier of the subscription
647 * @param int $item_id The id of the item
648 * @param string $method The method of the notification e.g. 'board', 'email', or 'jabber'
649 * (if null a subscription will be added for all the defaults methods)
650 * @param bool|int $user_id The user_id to add the subscription for (bool false for current user)
651 */
652 public function add_subscription($item_type, $item_id = 0, $method = null, $user_id = false)
653 {
654 if ($method === null)
655 {
656 foreach ($this->get_default_methods() as $method_name)
657 {
658 $this->add_subscription($item_type, $item_id, $method_name, $user_id);
659 }
660
661 return;
662 }
663
664 $user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id;
665
666 $sql = 'SELECT notify
667 FROM ' . $this->user_notifications_table . "
668 WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
669 AND item_id = " . (int) $item_id . '
670 AND user_id = ' .(int) $user_id . "
671 AND method = '" . $this->db->sql_escape($method) . "'";
672 $this->db->sql_query($sql);
673 $current = $this->db->sql_fetchfield('notify');
674 $this->db->sql_freeresult();
675
676 if ($current === false)
677 {
678 $sql = 'INSERT INTO ' . $this->user_notifications_table . ' ' .
679 $this->db->sql_build_array('INSERT', array(
680 'item_type' => $item_type,
681 'item_id' => (int) $item_id,
682 'user_id' => (int) $user_id,
683 'method' => $method,
684 'notify' => 1,
685 ));
686 $this->db->sql_query($sql);
687 }
688 else if (!$current)
689 {
690 $sql = 'UPDATE ' . $this->user_notifications_table . "
691 SET notify = 1
692 WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
693 AND item_id = " . (int) $item_id . '
694 AND user_id = ' .(int) $user_id . "
695 AND method = '" . $this->db->sql_escape($method) . "'";
696 $this->db->sql_query($sql);
697 }
698 }
699
700 /**
701 * Delete a subscription
702 *
703 * @param string $item_type Type identifier of the subscription
704 * @param int $item_id The id of the item
705 * @param string $method The method of the notification e.g. 'board', 'email', or 'jabber'
706 * @param bool|int $user_id The user_id to add the subscription for (bool false for current user)
707 */
708 public function delete_subscription($item_type, $item_id = 0, $method = null, $user_id = false)
709 {
710 if ($method === null)
711 {
712 foreach ($this->get_default_methods() as $method_name)
713 {
714 $this->delete_subscription($item_type, $item_id, $method_name, $user_id);
715 }
716
717 return;
718 }
719
720 $user_id = $user_id ?: $this->user->data['user_id'];
721
722 $sql = 'UPDATE ' . $this->user_notifications_table . "
723 SET notify = 0
724 WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
725 AND item_id = " . (int) $item_id . '
726 AND user_id = ' .(int) $user_id . "
727 AND method = '" . $this->db->sql_escape($method) . "'";
728 $this->db->sql_query($sql);
729
730 if (!$this->db->sql_affectedrows())
731 {
732 $sql = 'INSERT INTO ' . $this->user_notifications_table . ' ' .
733 $this->db->sql_build_array('INSERT', array(
734 'item_type' => $item_type,
735 'item_id' => (int) $item_id,
736 'user_id' => (int) $user_id,
737 'method' => $method,
738 'notify' => 0,
739 ));
740 $this->db->sql_query($sql);
741 }
742 }
743
744 /**
745 * Disable all notifications of a certain type
746 *
747 * This should be called when an extension which has notification types
748 * is disabled so that all those notifications are hidden and do not
749 * cause errors
750 *
751 * @param string $notification_type_name Type identifier of the subscription
752 */
753 public function disable_notifications($notification_type_name)
754 {
755 $sql = 'UPDATE ' . $this->notification_types_table . "
756 SET notification_type_enabled = 0
757 WHERE notification_type_name = '" . $this->db->sql_escape($notification_type_name) . "'";
758 $this->db->sql_query($sql);
759 }
760
761 /**
762 * Purge all notifications of a certain type
763 *
764 * This should be called when an extension which has notification types
765 * is purged so that all those notifications are removed
766 *
767 * @param string $notification_type_name Type identifier of the subscription
768 */
769 public function purge_notifications($notification_type_name)
770 {
771 // If a notification is never used, its type will not be added to the database
772 // nor its id cached. If this method is called by an extension during the
773 // purge step, and that extension never used its notifications,
774 // get_notification_type_id() will throw an exception. However,
775 // because no notification type was added to the database,
776 // there is nothing to delete, so we can silently drop the exception.
777 try
778 {
779 $notification_type_id = $this->get_notification_type_id($notification_type_name);
780
781 /** @var method\method_interface $method */
782 foreach ($this->get_available_subscription_methods() as $method)
783 {
784 $method->purge_notifications($notification_type_id);
785 }
786
787 }
788 catch (\phpbb\notification\exception $e)
789 {
790 // Continue
791 }
792 }
793
794 /**
795 * Enable all notifications of a certain type
796 *
797 * This should be called when an extension which has notification types
798 * that was disabled is re-enabled so that all those notifications that
799 * were hidden are shown again
800 *
801 * @param string $notification_type_name Type identifier of the subscription
802 */
803 public function enable_notifications($notification_type_name)
804 {
805 $sql = 'UPDATE ' . $this->notification_types_table . "
806 SET notification_type_enabled = 1
807 WHERE notification_type_name = '" . $this->db->sql_escape($notification_type_name) . "'";
808 $this->db->sql_query($sql);
809 }
810
811 /**
812 * Delete all notifications older than a certain time
813 *
814 * @param int $timestamp Unix timestamp to delete all notifications that were created before
815 * @param bool $only_read True (default) to only prune read notifications
816 */
817 public function prune_notifications($timestamp, $only_read = true)
818 {
819 /** @var method\method_interface $method */
820 foreach ($this->get_available_subscription_methods() as $method)
821 {
822 $method->prune_notifications($timestamp, $only_read);
823 }
824 }
825
826 /**
827 * Helper to get the list of methods enabled by default
828 *
829 * @return method\method_interface[]
830 */
831 public function get_default_methods()
832 {
833 $default_methods = array();
834
835 foreach ($this->notification_methods as $method)
836 {
837 if ($method->is_enabled_by_default() && $method->is_available())
838 {
839 $default_methods[] = $method->get_type();
840 }
841 }
842
843 return $default_methods;
844 }
845
846 /**
847 * Helper to get the notifications item type class and set it up
848 *
849 * @param string $notification_type_name
850 * @param array $data
851 * @return type\type_interface
852 */
853 public function get_item_type_class($notification_type_name, $data = array())
854 {
855 $item = $this->load_object($notification_type_name);
856
857 $item->set_initial_data($data);
858
859 return $item;
860 }
861
862 /**
863 * Helper to get the notifications method class and set it up
864 *
865 * @param string $method_name
866 * @return method\method_interface
867 */
868 public function get_method_class($method_name)
869 {
870 return $this->load_object($method_name);
871 }
872
873 /**
874 * Helper to load objects (notification types/methods)
875 *
876 * @param string $object_name
877 * @return method\method_interface|type\type_interface
878 */
879 protected function load_object($object_name)
880 {
881 $object = $this->phpbb_container->get($object_name);
882
883 if (method_exists($object, 'set_notification_manager'))
884 {
885 $object->set_notification_manager($this);
886 }
887
888 return $object;
889 }
890
891 /**
892 * Get the notification type id from the name
893 *
894 * @param string $notification_type_name The name
895 * @return int the notification_type_id
896 * @throws \phpbb\notification\exception
897 */
898 public function get_notification_type_id($notification_type_name)
899 {
900 $notification_type_ids = $this->cache->get('notification_type_ids');
901
902 $this->db->sql_transaction('begin');
903
904 if ($notification_type_ids === false)
905 {
906 $notification_type_ids = array();
907
908 $sql = 'SELECT notification_type_id, notification_type_name
909 FROM ' . $this->notification_types_table;
910 $result = $this->db->sql_query($sql);
911 while ($row = $this->db->sql_fetchrow($result))
912 {
913 $notification_type_ids[$row['notification_type_name']] = (int) $row['notification_type_id'];
914 }
915 $this->db->sql_freeresult($result);
916
917 $this->cache->put('notification_type_ids', $notification_type_ids);
918 }
919
920 if (!isset($notification_type_ids[$notification_type_name]))
921 {
922 if (!isset($this->notification_types[$notification_type_name]) && !isset($this->notification_types['notification.type.' . $notification_type_name]))
923 {
924 $this->db->sql_transaction('rollback');
925
926 throw new \phpbb\notification\exception('NOTIFICATION_TYPE_NOT_EXIST', array($notification_type_name));
927 }
928
929 $sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array(
930 'notification_type_name' => $notification_type_name,
931 'notification_type_enabled' => 1,
932 ));
933 $this->db->sql_query($sql);
934
935 $notification_type_ids[$notification_type_name] = (int) $this->db->sql_nextid();
936
937 $this->cache->put('notification_type_ids', $notification_type_ids);
938 }
939
940 $this->db->sql_transaction('commit');
941
942 return $notification_type_ids[$notification_type_name];
943 }
944
945 /**
946 * Get notification type ids (as an array)
947 *
948 * @param string|array $notification_type_names Notification type names
949 * @return array Array of integers
950 */
951 public function get_notification_type_ids($notification_type_names)
952 {
953 if (!is_array($notification_type_names))
954 {
955 $notification_type_names = array($notification_type_names);
956 }
957
958 $notification_type_ids = array();
959
960 foreach ($notification_type_names as $name)
961 {
962 $notification_type_ids[$name] = $this->get_notification_type_id($name);
963 }
964
965 return $notification_type_ids;
966 }
967
968 /**
969 * Find the users which are already notified
970 *
971 * @param bool|string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types). False to retrieve all item types
972 * @param array $options
973 * @return array The list of the notified users
974 */
975 public function get_notified_users($notification_type_name, array $options)
976 {
977 $notification_type_id = $this->get_notification_type_id($notification_type_name);
978
979 $notified_users = array();
980
981 /** @var method\method_interface $method */
982 foreach ($this->get_available_subscription_methods() as $method)
983 {
984 $notified_users = $notified_users + $method->get_notified_users($notification_type_id, $options);
985 }
986
987 return $notified_users;
988 }
989 }
990