Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
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
0001 <?php
0002 /**
0003 *
0004 * This file is part of the phpBB Forum Software package.
0005 *
0006 * @copyright (c) phpBB Limited <https://www.phpbb.com>
0007 * @license GNU General Public License, version 2 (GPL-2.0)
0008 *
0009 * For full copyright and license information, please see
0010 * the docs/CREDITS.txt file.
0011 *
0012 */
0013
0014 namespace phpbb\notification;
0015
0016 use Symfony\Component\DependencyInjection\ContainerInterface;
0017
0018 /**
0019 * Notifications service class
0020 */
0021 class manager
0022 {
0023 /** @var array */
0024 protected $notification_types;
0025
0026 /** @var array */
0027 protected $subscription_types;
0028
0029 /** @var method\method_interface[] */
0030 protected $notification_methods;
0031
0032 /** @var ContainerInterface */
0033 protected $phpbb_container;
0034
0035 /** @var \phpbb\user_loader */
0036 protected $user_loader;
0037
0038 /** @var \phpbb\event\dispatcher_interface */
0039 protected $phpbb_dispatcher;
0040
0041 /** @var \phpbb\db\driver\driver_interface */
0042 protected $db;
0043
0044 /** @var \phpbb\cache\service */
0045 protected $cache;
0046
0047 /** @var \phpbb\language\language */
0048 protected $language;
0049
0050 /** @var \phpbb\user */
0051 protected $user;
0052
0053 /** @var string */
0054 protected $notification_types_table;
0055
0056 /** @var string */
0057 protected $user_notifications_table;
0058
0059 /**
0060 * Notification Constructor
0061 *
0062 * @param array $notification_types
0063 * @param array $notification_methods
0064 * @param ContainerInterface $phpbb_container
0065 * @param \phpbb\user_loader $user_loader
0066 * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher
0067 * @param \phpbb\db\driver\driver_interface $db
0068 * @param \phpbb\cache\service $cache
0069 * @param \phpbb\language\language $language
0070 * @param \phpbb\user $user
0071 * @param string $notification_types_table
0072 * @param string $user_notifications_table
0073 *
0074 * @return \phpbb\notification\manager
0075 */
0076 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)
0077 {
0078 $this->notification_types = $notification_types;
0079 $this->notification_methods = $notification_methods;
0080 $this->phpbb_container = $phpbb_container;
0081
0082 $this->user_loader = $user_loader;
0083 $this->phpbb_dispatcher = $phpbb_dispatcher;
0084 $this->db = $db;
0085 $this->cache = $cache;
0086 $this->language = $language;
0087 $this->user = $user;
0088
0089 $this->notification_types_table = $notification_types_table;
0090 $this->user_notifications_table = $user_notifications_table;
0091 }
0092
0093 /**
0094 * Load the user's notifications for a given method
0095 *
0096 * @param string $method_name
0097 * @param array $options Optional options to control what notifications are loaded
0098 * notification_id Notification id to load (or array of notification ids)
0099 * user_id User id to load notifications for (Default: $user->data['user_id'])
0100 * order_by Order by (Default: notification_time)
0101 * order_dir Order direction (Default: DESC)
0102 * limit Number of notifications to load (Default: 5)
0103 * start Notifications offset (Default: 0)
0104 * all_unread Load all unread notifications? If set to true, count_unread is set to true (Default: false)
0105 * count_unread Count all unread notifications? (Default: false)
0106 * count_total Count all notifications? (Default: false)
0107 * @return array Array of information based on the request with keys:
0108 * 'notifications' array of notification type objects
0109 * 'unread_count' number of unread notifications the user has if count_unread is true in the options
0110 * 'total_count' number of notifications the user has if count_total is true in the options
0111 * @throws \phpbb\notification\exception when the method doesn't refer to a class extending \phpbb\notification\method\method_interface
0112 */
0113 public function load_notifications($method_name, array $options = array())
0114 {
0115 $method = $this->get_method_class($method_name);
0116
0117 if (! $method instanceof \phpbb\notification\method\method_interface)
0118 {
0119 throw new \phpbb\notification\exception($this->language->lang('NOTIFICATION_METHOD_INVALID', $method_name));
0120 }
0121 else if ($method->is_available())
0122 {
0123 return $method->load_notifications($options);
0124 }
0125 else
0126 {
0127 return array(
0128 'notifications' => array(),
0129 'unread_count' => 0,
0130 'total_count' => 0,
0131 );
0132 }
0133 }
0134
0135 /**
0136 * Mark notifications read or unread for all available methods
0137 *
0138 * @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
0139 * @param bool|int|array $item_id Item id or array of item ids. False to mark read for all item ids
0140 * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
0141 * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
0142 *
0143 * @deprecated since 3.2
0144 */
0145 public function mark_notifications_read($notification_type_name, $item_id, $user_id, $time = false)
0146 {
0147 $this->mark_notifications($notification_type_name, $item_id, $user_id, $time);
0148 }
0149
0150 /**
0151 * Mark notifications read or unread for all available methods
0152 *
0153 * @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
0154 * @param bool|int|array $item_id Item id or array of item ids. False to mark read for all item ids
0155 * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
0156 * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
0157 * @param bool $mark_read Define if the notification as to be set to True or False. (Default: True)
0158 */
0159 public function mark_notifications($notification_type_name, $item_id, $user_id, $time = false, $mark_read = true)
0160 {
0161 if (is_array($notification_type_name))
0162 {
0163 $notification_type_id = $this->get_notification_type_ids($notification_type_name);
0164 }
0165 else if ($notification_type_name !== false)
0166 {
0167 $notification_type_id = $this->get_notification_type_id($notification_type_name);
0168 }
0169 else
0170 {
0171 $notification_type_id = false;
0172 }
0173
0174 /** @var method\method_interface $method */
0175 foreach ($this->get_available_subscription_methods() as $method)
0176 {
0177 $method->mark_notifications($notification_type_id, $item_id, $user_id, $time, $mark_read);
0178 }
0179 }
0180
0181 /**
0182 * Mark notifications read or unread from a parent identifier for all available methods
0183 *
0184 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
0185 * @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
0186 * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
0187 * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
0188 *
0189 * @deprecated since 3.2
0190 */
0191 public function mark_notifications_read_by_parent($notification_type_name, $item_parent_id, $user_id, $time = false)
0192 {
0193 $this->mark_notifications_by_parent($notification_type_name, $item_parent_id, $user_id, $time);
0194 }
0195
0196 /**
0197 * Mark notifications read or unread from a parent identifier for all available methods
0198 *
0199 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
0200 * @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
0201 * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
0202 * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
0203 * @param bool $mark_read Define if the notification as to be set to True or False. (Default: True)
0204 */
0205 public function mark_notifications_by_parent($notification_type_name, $item_parent_id, $user_id, $time = false, $mark_read = true)
0206 {
0207 if (is_array($notification_type_name))
0208 {
0209 $notification_type_id = $this->get_notification_type_ids($notification_type_name);
0210 }
0211 else
0212 {
0213 $notification_type_id = $this->get_notification_type_id($notification_type_name);
0214 }
0215
0216 /** @var method\method_interface $method */
0217 foreach ($this->get_available_subscription_methods() as $method)
0218 {
0219 $method->mark_notifications_by_parent($notification_type_id, $item_parent_id, $user_id, $time, $mark_read);
0220 }
0221 }
0222
0223 /**
0224 * Mark notifications read or unread for a given method
0225 *
0226 * @param string $method_name
0227 * @param int|array $notification_id Notification id or array of notification ids.
0228 * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
0229 * @param bool $mark_read Define if the notification as to be set to True or False. (Default: True)
0230 */
0231 public function mark_notifications_by_id($method_name, $notification_id, $time = false, $mark_read = true)
0232 {
0233 $method = $this->get_method_class($method_name);
0234
0235 if ($method instanceof \phpbb\notification\method\method_interface && $method->is_available())
0236 {
0237 $method->mark_notifications_by_id($notification_id, $time, $mark_read);
0238 }
0239 }
0240
0241 /**
0242 * Add a notification
0243 *
0244 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
0245 * Note: If you send an array of types, any user who could receive multiple notifications from this single item will only receive
0246 * a single notification. If they MUST receive multiple notifications, call this function multiple times instead of sending an array
0247 * @param array $data Data specific for this type that will be inserted
0248 * @param array $options Optional options to control what notifications are loaded
0249 * ignore_users array of data to specify which users should not receive certain types of notifications
0250 * @return array Information about what users were notified and how they were notified
0251 */
0252 public function add_notifications($notification_type_name, $data, array $options = array())
0253 {
0254 $options = array_merge(array(
0255 'ignore_users' => array(),
0256 ), $options);
0257
0258 $notified_users = [];
0259 $add_notifications_override = false;
0260
0261 /**
0262 * Get notification data before find_users_for_notification() execute
0263 *
0264 * @event core.notification_manager_add_notifications_before
0265 * @var bool add_notifications_override Flag indicating whether function should return after event
0266 * @var array|string notification_type_name Type identifier or array of item types
0267 * @var string data Data specific for this notification type that will be inserted
0268 * @var array notified_users Array of notified users
0269 * @var string options Optional options to control what notifications are loaded
0270 * @since 3.3.6-RC1
0271 */
0272 $vars = [
0273 'add_notifications_override',
0274 'notification_type_name',
0275 'data',
0276 'notified_users',
0277 'options',
0278 ];
0279 extract($this->phpbb_dispatcher->trigger_event('core.notification_manager_add_notifications_before', compact($vars)));
0280
0281 if ($add_notifications_override)
0282 {
0283 return $notified_users;
0284 }
0285
0286 if (is_array($notification_type_name))
0287 {
0288 $temp_options = $options;
0289
0290 foreach ($notification_type_name as $type)
0291 {
0292 $temp_options['ignore_users'] = $options['ignore_users'] + $notified_users;
0293 $notified_users += $this->add_notifications($type, $data, $temp_options);
0294 }
0295
0296 return $notified_users;
0297 }
0298
0299 // find out which users want to receive this type of notification
0300 $notify_users = $this->get_item_type_class($notification_type_name)->find_users_for_notification($data, $options);
0301
0302 /**
0303 * Allow filtering the notify_users array for a notification that is about to be sent.
0304 * Here, $notify_users is already filtered by f_read and the ignored list included in the options variable
0305 *
0306 * @event core.notification_manager_add_notifications
0307 * @var string notification_type_name The notification type identifier
0308 * @var array data Data specific for the notification_type_name used will be inserted
0309 * @var array notify_users The array of userid that are going to be notified for this notification. Set to array() to cancel.
0310 * @var array options The options that were used when this method was called (read only)
0311 *
0312 * @since 3.1.3-RC1
0313 */
0314 $vars = array(
0315 'notification_type_name',
0316 'data',
0317 'notify_users',
0318 'options',
0319 );
0320 extract($this->phpbb_dispatcher->trigger_event('core.notification_manager_add_notifications', compact($vars)));
0321
0322 $this->add_notifications_for_users($notification_type_name, $data, $notify_users);
0323
0324 return $notify_users;
0325 }
0326
0327 /**
0328 * Add a notification for specific users
0329 *
0330 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
0331 * @param array $data Data specific for this type that will be inserted
0332 * @param array $notify_users User list to notify
0333 */
0334 public function add_notifications_for_users($notification_type_name, $data, $notify_users)
0335 {
0336 if (is_array($notification_type_name))
0337 {
0338 foreach ($notification_type_name as $type)
0339 {
0340 $this->add_notifications_for_users($type, $data, $notify_users);
0341 }
0342
0343 return;
0344 }
0345
0346 $notification_type_id = $this->get_notification_type_id($notification_type_name);
0347
0348 $item_id = $this->get_item_type_class($notification_type_name)->get_item_id($data);
0349
0350 $user_ids = array();
0351 $notification_methods = array();
0352
0353 // Never send notifications to the anonymous user!
0354 unset($notify_users[ANONYMOUS]);
0355
0356 // Make sure not to send new notifications to users who've already been notified about this item
0357 // This may happen when an item was added, but now new users are able to see the item
0358 // We remove each user which was already notified by at least one method.
0359 /** @var method\method_interface $method */
0360 foreach ($this->get_subscription_methods_instances() as $method)
0361 {
0362 $notified_users = $method->get_notified_users($notification_type_id, array('item_id' => $item_id));
0363
0364 foreach ($notified_users as $user => $notifications)
0365 {
0366 unset($notify_users[$user]);
0367 }
0368 }
0369
0370 /**
0371 * Allow filtering the $notify_users array by $notification_type_name for a notification that is about to be sent.
0372 * Here, $notify_users is already filtered from users who've already been notified.
0373 *
0374 * @event core.notification_manager_add_notifications_for_users_modify_data
0375 * @var string notification_type_name The notification type identifier
0376 * @var array data Data specific for this type that will be inserted
0377 * @var array notify_users User list to notify
0378 *
0379 * @since 3.2.10-RC1
0380 * @since 3.3.1-RC1
0381 */
0382 $vars = [
0383 'notification_type_name',
0384 'data',
0385 'notify_users',
0386 ];
0387 extract($this->phpbb_dispatcher->trigger_event('core.notification_manager_add_notifications_for_users_modify_data', compact($vars)));
0388
0389 if (!count($notify_users))
0390 {
0391 return;
0392 }
0393
0394 // Allow notifications to perform actions before creating the insert array (such as run a query to cache some data needed for all notifications)
0395 $notification = $this->get_item_type_class($notification_type_name);
0396 $pre_create_data = $notification->pre_create_insert_array($data, $notify_users);
0397 unset($notification);
0398
0399 // Go through each user so we can insert a row in the DB and then notify them by their desired means
0400 foreach ($notify_users as $user => $methods)
0401 {
0402 $notification = $this->get_item_type_class($notification_type_name);
0403
0404 $notification->user_id = (int) $user;
0405
0406 // Generate the insert_array
0407 $notification->create_insert_array($data, $pre_create_data);
0408
0409 // Users are needed to send notifications
0410 $user_ids = array_merge($user_ids, $notification->users_to_query());
0411
0412 foreach ($methods as $method)
0413 {
0414 // Do not load non-existent notification methods
0415 if (!isset($this->notification_methods[$method]))
0416 {
0417 continue;
0418 }
0419
0420 // Setup the notification methods and add the notification to the queue
0421 if (!isset($notification_methods[$method]))
0422 {
0423 $notification_methods[$method] = $this->get_method_class($method);
0424 }
0425 $notification_methods[$method]->add_to_queue($notification);
0426 }
0427 }
0428
0429 // We need to load all of the users to send notifications
0430 $this->user_loader->load_users($user_ids);
0431
0432 // run the queue for each method to send notifications
0433 foreach ($notification_methods as $method)
0434 {
0435 $method->notify();
0436 }
0437 }
0438
0439 /**
0440 * Update notification
0441 *
0442 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
0443 * @param array $data Data specific for this type that will be updated
0444 * @param array $options
0445 */
0446 public function update_notifications($notification_type_name, array $data, array $options = array())
0447 {
0448 if (is_array($notification_type_name))
0449 {
0450 foreach ($notification_type_name as $type)
0451 {
0452 $this->update_notifications($type, $data);
0453 }
0454
0455 return;
0456 }
0457
0458 $this->update_notification($this->get_item_type_class($notification_type_name), $data, $options);
0459 }
0460
0461 /**
0462 * Update a notification
0463 *
0464 * @param \phpbb\notification\type\type_interface $notification The notification
0465 * @param array $data Data specific for this type that will be updated
0466 * @param array $options
0467 */
0468 public function update_notification(\phpbb\notification\type\type_interface $notification, array $data, array $options = array())
0469 {
0470 if (empty($options))
0471 {
0472 $options['item_id'] = $notification->get_item_id($data);
0473 }
0474
0475 /** @var method\method_interface $method */
0476 foreach ($this->get_available_subscription_methods() as $method)
0477 {
0478 $method->update_notification($notification, $data, $options);
0479 }
0480 }
0481
0482 /**
0483 * Delete a notification
0484 *
0485 * @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)
0486 * @param int|array $item_id Identifier within the type (or array of ids)
0487 * @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)
0488 * @param mixed $user_id User id (Default: false; not checked)
0489 */
0490 public function delete_notifications($notification_type_name, $item_id, $parent_id = false, $user_id = false)
0491 {
0492 if (is_array($notification_type_name))
0493 {
0494 foreach ($notification_type_name as $type)
0495 {
0496 $this->delete_notifications($type, $item_id, $parent_id, $user_id);
0497 }
0498
0499 return;
0500 }
0501
0502 $notification_type_id = $this->get_notification_type_id($notification_type_name);
0503
0504 /** @var method\method_interface $method */
0505 foreach ($this->get_available_subscription_methods() as $method)
0506 {
0507 $method->delete_notifications($notification_type_id, $item_id, $parent_id, $user_id);
0508 }
0509 }
0510
0511 /**
0512 * Get all of the subscription types
0513 *
0514 * @return array Array of item types
0515 */
0516 public function get_subscription_types()
0517 {
0518 if ($this->subscription_types === null)
0519 {
0520 $this->subscription_types = array();
0521
0522 foreach ($this->notification_types as $type_name => $data)
0523 {
0524 /** @var type\base $type */
0525 $type = $this->get_item_type_class($type_name);
0526
0527 if ($type instanceof \phpbb\notification\type\type_interface && $type->is_available())
0528 {
0529 $options = array_merge(array(
0530 'type' => $type,
0531 'id' => $type->get_type(),
0532 'lang' => 'NOTIFICATION_TYPE_' . strtoupper($type->get_type()),
0533 'group' => 'NOTIFICATION_GROUP_MISCELLANEOUS',
0534 ), (($type::$notification_option !== false) ? $type::$notification_option : array()));
0535
0536 $this->subscription_types[$options['group']][$options['id']] = $options;
0537 }
0538 }
0539
0540 // Move Miscellaneous to the very last section
0541 if (isset($this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS']))
0542 {
0543 $miscellaneous = $this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS'];
0544 unset($this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS']);
0545 $this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS'] = $miscellaneous;
0546 }
0547 }
0548
0549 return $this->subscription_types;
0550 }
0551
0552 /**
0553 * Get all of the subscription methods
0554 *
0555 * @return array Array of methods
0556 */
0557 public function get_subscription_methods()
0558 {
0559 $subscription_methods = array();
0560
0561 /** @var method\method_interface $method */
0562 foreach ($this->get_available_subscription_methods() as $method_name => $method)
0563 {
0564 $subscription_methods[$method_name] = array(
0565 'method' => $method,
0566 'id' => $method->get_type(),
0567 'lang' => str_replace('.', '_', strtoupper($method->get_type())),
0568 );
0569 }
0570
0571 return $subscription_methods;
0572 }
0573
0574 /**
0575 * Get all of the subscription methods
0576 *
0577 * @return array Array of method's instances
0578 */
0579 private function get_subscription_methods_instances()
0580 {
0581 $subscription_methods = array();
0582
0583 foreach ($this->notification_methods as $method_name => $data)
0584 {
0585 $method = $this->get_method_class($method_name);
0586
0587 if ($method instanceof \phpbb\notification\method\method_interface)
0588 {
0589 $subscription_methods[$method_name] = $method;
0590 }
0591 }
0592
0593 return $subscription_methods;
0594 }
0595
0596 /**
0597 * Get all of the available subscription methods
0598 *
0599 * @return array Array of method's instances
0600 */
0601 private function get_available_subscription_methods()
0602 {
0603 $subscription_methods = array();
0604
0605 /** @var method\method_interface $method */
0606 foreach ($this->get_subscription_methods_instances() as $method_name => $method)
0607 {
0608 if ($method->is_available())
0609 {
0610 $subscription_methods[$method_name] = $method;
0611 }
0612 }
0613
0614 return $subscription_methods;
0615 }
0616
0617
0618 /**
0619 * Get user's notification data
0620 *
0621 * @param int $user_id The user_id of the user to get the notifications for
0622 *
0623 * @return array User's notification
0624 */
0625 protected function get_user_notifications($user_id)
0626 {
0627 $sql = 'SELECT method, notify, item_type
0628 FROM ' . $this->user_notifications_table . '
0629 WHERE user_id = ' . (int) $user_id . '
0630 AND item_id = 0';
0631
0632 $result = $this->db->sql_query($sql);
0633 $user_notifications = array();
0634
0635 while ($row = $this->db->sql_fetchrow($result))
0636 {
0637 $user_notifications[$row['item_type']][] = $row;
0638 }
0639
0640 $this->db->sql_freeresult($result);
0641
0642 return $user_notifications;
0643 }
0644
0645 /**
0646 * Get global subscriptions (item_id = 0)
0647 *
0648 * @param bool|int $user_id The user_id to add the subscription for (bool false for current user)
0649 *
0650 * @return array Subscriptions
0651 */
0652 public function get_global_subscriptions($user_id = false)
0653 {
0654 $user_id = $user_id ?: $this->user->data['user_id'];
0655
0656 $subscriptions = array();
0657 $default_methods = $this->get_default_methods();
0658
0659 $user_notifications = $this->get_user_notifications($user_id);
0660
0661 foreach ($this->get_subscription_types() as $types)
0662 {
0663 foreach ($types as $id => $type)
0664 {
0665 $type_subscriptions = $default_methods;
0666 if (!empty($user_notifications[$id]))
0667 {
0668 foreach ($user_notifications[$id] as $user_notification)
0669 {
0670 $key = array_search($user_notification['method'], $type_subscriptions, true);
0671 if (!$user_notification['notify'])
0672 {
0673 if ($key !== false)
0674 {
0675 unset($type_subscriptions[$key]);
0676 }
0677
0678 continue;
0679 }
0680 else if ($key === false)
0681 {
0682 $type_subscriptions[] = $user_notification['method'];
0683 }
0684 }
0685 }
0686
0687 if (!empty($type_subscriptions))
0688 {
0689 $subscriptions[$id] = $type_subscriptions;
0690 }
0691 }
0692 }
0693
0694 return $subscriptions;
0695 }
0696
0697 /**
0698 * Add a subscription
0699 *
0700 * @param string $item_type Type identifier of the subscription
0701 * @param int $item_id The id of the item
0702 * @param string $method The method of the notification e.g. 'board', 'email', or 'jabber'
0703 * (if null a subscription will be added for all the defaults methods)
0704 * @param bool|int $user_id The user_id to add the subscription for (bool false for current user)
0705 */
0706 public function add_subscription($item_type, $item_id = 0, $method = null, $user_id = false)
0707 {
0708 if ($method === null)
0709 {
0710 foreach ($this->get_default_methods() as $method_name)
0711 {
0712 $this->add_subscription($item_type, $item_id, $method_name, $user_id);
0713 }
0714
0715 return;
0716 }
0717
0718 $user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id;
0719
0720 $sql = 'SELECT notify
0721 FROM ' . $this->user_notifications_table . "
0722 WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
0723 AND item_id = " . (int) $item_id . '
0724 AND user_id = ' .(int) $user_id . "
0725 AND method = '" . $this->db->sql_escape($method) . "'";
0726 $this->db->sql_query($sql);
0727 $current = $this->db->sql_fetchfield('notify');
0728 $this->db->sql_freeresult();
0729
0730 if ($current === false)
0731 {
0732 $sql = 'INSERT INTO ' . $this->user_notifications_table . ' ' .
0733 $this->db->sql_build_array('INSERT', array(
0734 'item_type' => $item_type,
0735 'item_id' => (int) $item_id,
0736 'user_id' => (int) $user_id,
0737 'method' => $method,
0738 'notify' => 1,
0739 ));
0740 $this->db->sql_query($sql);
0741 }
0742 else if (!$current)
0743 {
0744 $sql = 'UPDATE ' . $this->user_notifications_table . "
0745 SET notify = 1
0746 WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
0747 AND item_id = " . (int) $item_id . '
0748 AND user_id = ' .(int) $user_id . "
0749 AND method = '" . $this->db->sql_escape($method) . "'";
0750 $this->db->sql_query($sql);
0751 }
0752 }
0753
0754 /**
0755 * Delete a subscription
0756 *
0757 * @param string $item_type Type identifier of the subscription
0758 * @param int $item_id The id of the item
0759 * @param string $method The method of the notification e.g. 'board', 'email', or 'jabber'
0760 * @param bool|int $user_id The user_id to add the subscription for (bool false for current user)
0761 */
0762 public function delete_subscription($item_type, $item_id = 0, $method = null, $user_id = false)
0763 {
0764 if ($method === null)
0765 {
0766 foreach ($this->get_default_methods() as $method_name)
0767 {
0768 $this->delete_subscription($item_type, $item_id, $method_name, $user_id);
0769 }
0770
0771 return;
0772 }
0773
0774 $user_id = $user_id ?: $this->user->data['user_id'];
0775
0776 $sql = 'UPDATE ' . $this->user_notifications_table . "
0777 SET notify = 0
0778 WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
0779 AND item_id = " . (int) $item_id . '
0780 AND user_id = ' .(int) $user_id . "
0781 AND method = '" . $this->db->sql_escape($method) . "'";
0782 $this->db->sql_query($sql);
0783
0784 if (!$this->db->sql_affectedrows())
0785 {
0786 $sql = 'INSERT INTO ' . $this->user_notifications_table . ' ' .
0787 $this->db->sql_build_array('INSERT', array(
0788 'item_type' => $item_type,
0789 'item_id' => (int) $item_id,
0790 'user_id' => (int) $user_id,
0791 'method' => $method,
0792 'notify' => 0,
0793 ));
0794 $this->db->sql_query($sql);
0795 }
0796 }
0797
0798 /**
0799 * Disable all notifications of a certain type
0800 *
0801 * This should be called when an extension which has notification types
0802 * is disabled so that all those notifications are hidden and do not
0803 * cause errors
0804 *
0805 * @param string $notification_type_name Type identifier of the subscription
0806 */
0807 public function disable_notifications($notification_type_name)
0808 {
0809 $sql = 'UPDATE ' . $this->notification_types_table . "
0810 SET notification_type_enabled = 0
0811 WHERE notification_type_name = '" . $this->db->sql_escape($notification_type_name) . "'";
0812 $this->db->sql_query($sql);
0813 }
0814
0815 /**
0816 * Purge all notifications of a certain type
0817 *
0818 * This should be called when an extension which has notification types
0819 * is purged so that all those notifications are removed
0820 *
0821 * @param string $notification_type_name Type identifier of the subscription
0822 */
0823 public function purge_notifications($notification_type_name)
0824 {
0825 // If a notification is never used, its type will not be added to the database
0826 // nor its id cached. If this method is called by an extension during the
0827 // purge step, and that extension never used its notifications,
0828 // get_notification_type_id() will throw an exception. However,
0829 // because no notification type was added to the database,
0830 // there is nothing to delete, so we can silently drop the exception.
0831 try
0832 {
0833 $notification_type_id = $this->get_notification_type_id($notification_type_name);
0834
0835 /** @var method\method_interface $method */
0836 foreach ($this->get_available_subscription_methods() as $method)
0837 {
0838 $method->purge_notifications($notification_type_id);
0839 }
0840
0841 }
0842 catch (\phpbb\notification\exception $e)
0843 {
0844 // Continue
0845 }
0846 }
0847
0848 /**
0849 * Enable all notifications of a certain type
0850 *
0851 * This should be called when an extension which has notification types
0852 * that was disabled is re-enabled so that all those notifications that
0853 * were hidden are shown again
0854 *
0855 * @param string $notification_type_name Type identifier of the subscription
0856 */
0857 public function enable_notifications($notification_type_name)
0858 {
0859 $sql = 'UPDATE ' . $this->notification_types_table . "
0860 SET notification_type_enabled = 1
0861 WHERE notification_type_name = '" . $this->db->sql_escape($notification_type_name) . "'";
0862 $this->db->sql_query($sql);
0863 }
0864
0865 /**
0866 * Delete all notifications older than a certain time
0867 *
0868 * @param int $timestamp Unix timestamp to delete all notifications that were created before
0869 * @param bool $only_read True (default) to only prune read notifications
0870 */
0871 public function prune_notifications($timestamp, $only_read = true)
0872 {
0873 /** @var method\method_interface $method */
0874 foreach ($this->get_available_subscription_methods() as $method)
0875 {
0876 $method->prune_notifications($timestamp, $only_read);
0877 }
0878 }
0879
0880 /**
0881 * Helper to get the list of methods enabled by default
0882 *
0883 * @return method\method_interface[]
0884 */
0885 public function get_default_methods()
0886 {
0887 $default_methods = array();
0888
0889 foreach ($this->notification_methods as $method)
0890 {
0891 if ($method->is_enabled_by_default() && $method->is_available())
0892 {
0893 $default_methods[] = $method->get_type();
0894 }
0895 }
0896
0897 return $default_methods;
0898 }
0899
0900 /**
0901 * Helper to get the notifications item type class and set it up
0902 *
0903 * @param string $notification_type_name
0904 * @param array $data
0905 * @return type\type_interface
0906 */
0907 public function get_item_type_class($notification_type_name, $data = array())
0908 {
0909 $item = $this->load_object($notification_type_name);
0910
0911 $item->set_initial_data($data);
0912
0913 return $item;
0914 }
0915
0916 /**
0917 * Helper to get the notifications method class and set it up
0918 *
0919 * @param string $method_name
0920 * @return method\method_interface
0921 */
0922 public function get_method_class($method_name)
0923 {
0924 return $this->load_object($method_name);
0925 }
0926
0927 /**
0928 * Helper to load objects (notification types/methods)
0929 *
0930 * @param string $object_name
0931 * @return method\method_interface|type\type_interface
0932 */
0933 protected function load_object($object_name)
0934 {
0935 $object = $this->phpbb_container->get($object_name);
0936
0937 if (method_exists($object, 'set_notification_manager'))
0938 {
0939 $object->set_notification_manager($this);
0940 }
0941
0942 return $object;
0943 }
0944
0945 /**
0946 * Get the notification type id from the name
0947 *
0948 * @param string $notification_type_name The name
0949 * @return int the notification_type_id
0950 * @throws \phpbb\notification\exception
0951 */
0952 public function get_notification_type_id($notification_type_name)
0953 {
0954 $sql = 'SELECT notification_type_id, notification_type_name
0955 FROM ' . $this->notification_types_table;
0956 $result = $this->db->sql_query($sql, 604800); // cache for one week
0957 while ($row = $this->db->sql_fetchrow($result))
0958 {
0959 $notification_type_ids[$row['notification_type_name']] = (int) $row['notification_type_id'];
0960 }
0961 $this->db->sql_freeresult($result);
0962
0963 if (!isset($notification_type_ids[$notification_type_name]))
0964 {
0965 if (!isset($this->notification_types[$notification_type_name]) && !isset($this->notification_types['notification.type.' . $notification_type_name]))
0966 {
0967 throw new \phpbb\notification\exception('NOTIFICATION_TYPE_NOT_EXIST', array($notification_type_name));
0968 }
0969
0970 $sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array(
0971 'notification_type_name' => $notification_type_name,
0972 'notification_type_enabled' => 1,
0973 ));
0974 $this->db->sql_query($sql);
0975
0976 // expose new notification type ID for this request
0977 $notification_type_ids[$notification_type_name] = (int) $this->db->sql_nextid();
0978
0979 // destroy cache, we have a new addition which we have to to load next time
0980 $this->cache->destroy('sql', $this->notification_types_table);
0981 }
0982
0983 return $notification_type_ids[$notification_type_name];
0984 }
0985
0986 /**
0987 * Get notification type ids (as an array)
0988 *
0989 * @param string|array $notification_type_names Notification type names
0990 * @return array Array of integers
0991 */
0992 public function get_notification_type_ids($notification_type_names)
0993 {
0994 if (!is_array($notification_type_names))
0995 {
0996 $notification_type_names = array($notification_type_names);
0997 }
0998
0999 $notification_type_ids = array();
1000
1001 foreach ($notification_type_names as $name)
1002 {
1003 $notification_type_ids[$name] = $this->get_notification_type_id($name);
1004 }
1005
1006 return $notification_type_ids;
1007 }
1008
1009 /**
1010 * Find the users which are already notified
1011 *
1012 * @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
1013 * @param array $options
1014 * @return array The list of the notified users
1015 */
1016 public function get_notified_users($notification_type_name, array $options)
1017 {
1018 $notification_type_id = $this->get_notification_type_id($notification_type_name);
1019
1020 $notified_users = array();
1021
1022 /** @var method\method_interface $method */
1023 foreach ($this->get_available_subscription_methods() as $method)
1024 {
1025 $notified_users = $notified_users + $method->get_notified_users($notification_type_id, $options);
1026 }
1027
1028 return $notified_users;
1029 }
1030 }
1031