[ Index ]

PHP Cross Reference of phpBB-3.3.10-deutsch

title

Body

[close]

/phpbb/notification/ -> manager.php (source)

   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;
  15  
  16  use Symfony\Component\DependencyInjection\ContainerInterface;
  17  
  18  /**
  19  * Notifications service class
  20  */
  21  class manager
  22  {
  23      /** @var array */
  24      protected $notification_types;
  25  
  26      /** @var array */
  27      protected $subscription_types;
  28  
  29      /** @var method\method_interface[] */
  30      protected $notification_methods;
  31  
  32      /** @var ContainerInterface */
  33      protected $phpbb_container;
  34  
  35      /** @var \phpbb\user_loader */
  36      protected $user_loader;
  37  
  38      /** @var \phpbb\event\dispatcher_interface */
  39      protected $phpbb_dispatcher;
  40  
  41      /** @var \phpbb\db\driver\driver_interface */
  42      protected $db;
  43  
  44      /** @var \phpbb\cache\service */
  45      protected $cache;
  46  
  47      /** @var \phpbb\language\language */
  48      protected $language;
  49  
  50      /** @var \phpbb\user */
  51      protected $user;
  52  
  53      /** @var string */
  54      protected $notification_types_table;
  55  
  56      /** @var string */
  57      protected $user_notifications_table;
  58  
  59      /**
  60      * Notification Constructor
  61      *
  62      * @param array $notification_types
  63      * @param array $notification_methods
  64      * @param ContainerInterface $phpbb_container
  65      * @param \phpbb\user_loader $user_loader
  66      * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher
  67      * @param \phpbb\db\driver\driver_interface $db
  68      * @param \phpbb\cache\service $cache
  69      * @param \phpbb\language\language $language
  70      * @param \phpbb\user $user
  71      * @param string $notification_types_table
  72      * @param string $user_notifications_table
  73      *
  74      * @return \phpbb\notification\manager
  75      */
  76  	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)
  77      {
  78          $this->notification_types = $notification_types;
  79          $this->notification_methods = $notification_methods;
  80          $this->phpbb_container = $phpbb_container;
  81  
  82          $this->user_loader = $user_loader;
  83          $this->phpbb_dispatcher = $phpbb_dispatcher;
  84          $this->db = $db;
  85          $this->cache = $cache;
  86          $this->language = $language;
  87          $this->user = $user;
  88  
  89          $this->notification_types_table = $notification_types_table;
  90          $this->user_notifications_table = $user_notifications_table;
  91      }
  92  
  93      /**
  94      * Load the user's notifications for a given method
  95      *
  96      * @param string $method_name
  97      * @param array $options Optional options to control what notifications are loaded
  98      *                notification_id        Notification id to load (or array of notification ids)
  99      *                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          $notified_users = [];
 259          $add_notifications_override = false;
 260  
 261          /**
 262          * Get notification data before find_users_for_notification() execute
 263          *
 264          * @event core.notification_manager_add_notifications_before
 265          * @var    bool            add_notifications_override    Flag indicating whether function should return after event
 266          * @var    array|string    notification_type_name        Type identifier or array of item types
 267          * @var    string            data                        Data specific for this notification type that will be inserted
 268          * @var    array             notified_users                Array of notified users
 269          * @var    string            options                        Optional options to control what notifications are loaded
 270          * @since 3.3.6-RC1
 271          */
 272          $vars = [
 273              'add_notifications_override',
 274              'notification_type_name',
 275              'data',
 276              'notified_users',
 277              'options',
 278          ];
 279          extract($this->phpbb_dispatcher->trigger_event('core.notification_manager_add_notifications_before', compact($vars)));
 280  
 281          if ($add_notifications_override)
 282          {
 283              return $notified_users;
 284          }
 285  
 286          if (is_array($notification_type_name))
 287          {
 288              $temp_options = $options;
 289  
 290              foreach ($notification_type_name as $type)
 291              {
 292                  $temp_options['ignore_users'] = $options['ignore_users'] + $notified_users;
 293                  $notified_users += $this->add_notifications($type, $data, $temp_options);
 294              }
 295  
 296              return $notified_users;
 297          }
 298  
 299          // find out which users want to receive this type of notification
 300          $notify_users = $this->get_item_type_class($notification_type_name)->find_users_for_notification($data, $options);
 301  
 302          /**
 303          * Allow filtering the notify_users array for a notification that is about to be sent.
 304          * Here, $notify_users is already filtered by f_read and the ignored list included in the options variable
 305          *
 306          * @event core.notification_manager_add_notifications
 307          * @var    string    notification_type_name        The notification type identifier
 308          * @var    array     data                        Data specific for the notification_type_name used will be inserted
 309          * @var    array     notify_users                The array of userid that are going to be notified for this notification. Set to array() to cancel.
 310          * @var    array     options                        The options that were used when this method was called (read only)
 311          *
 312          * @since 3.1.3-RC1
 313          */
 314          $vars = array(
 315              'notification_type_name',
 316              'data',
 317              'notify_users',
 318              'options',
 319          );
 320          extract($this->phpbb_dispatcher->trigger_event('core.notification_manager_add_notifications', compact($vars)));
 321  
 322          $this->add_notifications_for_users($notification_type_name, $data, $notify_users);
 323  
 324          return $notify_users;
 325      }
 326  
 327      /**
 328      * Add a notification for specific users
 329      *
 330      * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
 331      * @param array $data Data specific for this type that will be inserted
 332      * @param array $notify_users User list to notify
 333      */
 334  	public function add_notifications_for_users($notification_type_name, $data, $notify_users)
 335      {
 336          if (is_array($notification_type_name))
 337          {
 338              foreach ($notification_type_name as $type)
 339              {
 340                  $this->add_notifications_for_users($type, $data, $notify_users);
 341              }
 342  
 343              return;
 344          }
 345  
 346          $notification_type_id = $this->get_notification_type_id($notification_type_name);
 347  
 348          $item_id = $this->get_item_type_class($notification_type_name)->get_item_id($data);
 349  
 350          $user_ids = array();
 351          $notification_methods = array();
 352  
 353          // Never send notifications to the anonymous user!
 354          unset($notify_users[ANONYMOUS]);
 355  
 356          // Make sure not to send new notifications to users who've already been notified about this item
 357          // This may happen when an item was added, but now new users are able to see the item
 358          // We remove each user which was already notified by at least one method.
 359          /** @var method\method_interface $method */
 360          foreach ($this->get_subscription_methods_instances() as $method)
 361          {
 362              $notified_users = $method->get_notified_users($notification_type_id, array('item_id' => $item_id));
 363  
 364              foreach ($notified_users as $user => $notifications)
 365              {
 366                  unset($notify_users[$user]);
 367              }
 368          }
 369  
 370          /**
 371          * Allow filtering the $notify_users array by $notification_type_name for a notification that is about to be sent.
 372          * Here, $notify_users is already filtered from users who've already been notified.
 373          *
 374          * @event core.notification_manager_add_notifications_for_users_modify_data
 375          * @var    string    notification_type_name        The notification type identifier
 376          * @var    array     data                        Data specific for this type that will be inserted
 377          * @var    array     notify_users                User list to notify
 378          *
 379          * @since 3.2.10-RC1
 380          * @since 3.3.1-RC1
 381          */
 382          $vars = [
 383              'notification_type_name',
 384              'data',
 385              'notify_users',
 386          ];
 387          extract($this->phpbb_dispatcher->trigger_event('core.notification_manager_add_notifications_for_users_modify_data', compact($vars)));
 388  
 389          if (!count($notify_users))
 390          {
 391              return;
 392          }
 393  
 394          // Allow notifications to perform actions before creating the insert array (such as run a query to cache some data needed for all notifications)
 395          $notification = $this->get_item_type_class($notification_type_name);
 396          $pre_create_data = $notification->pre_create_insert_array($data, $notify_users);
 397          unset($notification);
 398  
 399          // Go through each user so we can insert a row in the DB and then notify them by their desired means
 400          foreach ($notify_users as $user => $methods)
 401          {
 402              $notification = $this->get_item_type_class($notification_type_name);
 403  
 404              $notification->user_id = (int) $user;
 405  
 406              // Generate the insert_array
 407              $notification->create_insert_array($data, $pre_create_data);
 408  
 409              // Users are needed to send notifications
 410              $user_ids = array_merge($user_ids, $notification->users_to_query());
 411  
 412              foreach ($methods as $method)
 413              {
 414                  // setup the notification methods and add the notification to the queue
 415                  if (!isset($notification_methods[$method]))
 416                  {
 417                      $notification_methods[$method] = $this->get_method_class($method);
 418                  }
 419  
 420                  $notification_methods[$method]->add_to_queue($notification);
 421              }
 422          }
 423  
 424          // We need to load all of the users to send notifications
 425          $this->user_loader->load_users($user_ids);
 426  
 427          // run the queue for each method to send notifications
 428          foreach ($notification_methods as $method)
 429          {
 430              $method->notify();
 431          }
 432      }
 433  
 434      /**
 435      * Update notification
 436      *
 437      * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
 438      * @param array $data Data specific for this type that will be updated
 439      * @param array $options
 440      */
 441  	public function update_notifications($notification_type_name, array $data, array $options = array())
 442      {
 443          if (is_array($notification_type_name))
 444          {
 445              foreach ($notification_type_name as $type)
 446              {
 447                  $this->update_notifications($type, $data);
 448              }
 449  
 450              return;
 451          }
 452  
 453          $this->update_notification($this->get_item_type_class($notification_type_name), $data, $options);
 454      }
 455  
 456      /**
 457      * Update a notification
 458      *
 459      * @param \phpbb\notification\type\type_interface $notification The notification
 460      * @param array $data Data specific for this type that will be updated
 461      * @param array $options
 462      */
 463  	public function update_notification(\phpbb\notification\type\type_interface $notification, array $data, array $options = array())
 464      {
 465          if (empty($options))
 466          {
 467              $options['item_id'] = $notification->get_item_id($data);
 468          }
 469  
 470          /** @var method\method_interface $method */
 471          foreach ($this->get_available_subscription_methods() as $method)
 472          {
 473              $method->update_notification($notification, $data, $options);
 474          }
 475      }
 476  
 477      /**
 478      * Delete a notification
 479      *
 480      * @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)
 481      * @param int|array $item_id Identifier within the type (or array of ids)
 482      * @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)
 483      * @param mixed $user_id User id (Default: false; not checked)
 484      */
 485  	public function delete_notifications($notification_type_name, $item_id, $parent_id = false, $user_id = false)
 486      {
 487          if (is_array($notification_type_name))
 488          {
 489              foreach ($notification_type_name as $type)
 490              {
 491                  $this->delete_notifications($type, $item_id, $parent_id, $user_id);
 492              }
 493  
 494              return;
 495          }
 496  
 497          $notification_type_id = $this->get_notification_type_id($notification_type_name);
 498  
 499          /** @var method\method_interface $method */
 500          foreach ($this->get_available_subscription_methods() as $method)
 501          {
 502              $method->delete_notifications($notification_type_id, $item_id, $parent_id, $user_id);
 503          }
 504      }
 505  
 506      /**
 507      * Get all of the subscription types
 508      *
 509      * @return array Array of item types
 510      */
 511  	public function get_subscription_types()
 512      {
 513          if ($this->subscription_types === null)
 514          {
 515              $this->subscription_types = array();
 516  
 517              foreach ($this->notification_types as $type_name => $data)
 518              {
 519                  /** @var type\base $type */
 520                  $type = $this->get_item_type_class($type_name);
 521  
 522                  if ($type instanceof \phpbb\notification\type\type_interface && $type->is_available())
 523                  {
 524                      $options = array_merge(array(
 525                          'type'    => $type,
 526                          'id'    => $type->get_type(),
 527                          'lang'    => 'NOTIFICATION_TYPE_' . strtoupper($type->get_type()),
 528                          'group'    => 'NOTIFICATION_GROUP_MISCELLANEOUS',
 529                      ), (($type::$notification_option !== false) ? $type::$notification_option : array()));
 530  
 531                      $this->subscription_types[$options['group']][$options['id']] = $options;
 532                  }
 533              }
 534  
 535              // Move Miscellaneous to the very last section
 536              if (isset($this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS']))
 537              {
 538                  $miscellaneous = $this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS'];
 539                  unset($this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS']);
 540                  $this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS'] = $miscellaneous;
 541              }
 542          }
 543  
 544          return $this->subscription_types;
 545      }
 546  
 547      /**
 548      * Get all of the subscription methods
 549      *
 550      * @return array Array of methods
 551      */
 552  	public function get_subscription_methods()
 553      {
 554          $subscription_methods = array();
 555  
 556          /** @var method\method_interface $method */
 557          foreach ($this->get_available_subscription_methods() as $method_name => $method)
 558          {
 559              $subscription_methods[$method_name] = array(
 560                  'method'    => $method,
 561                  'id'        => $method->get_type(),
 562                  'lang'        => str_replace('.', '_', strtoupper($method->get_type())),
 563              );
 564          }
 565  
 566          return $subscription_methods;
 567      }
 568  
 569      /**
 570      * Get all of the subscription methods
 571      *
 572      * @return array Array of method's instances
 573      */
 574  	private function get_subscription_methods_instances()
 575      {
 576          $subscription_methods = array();
 577  
 578          foreach ($this->notification_methods as $method_name => $data)
 579          {
 580              $method = $this->get_method_class($method_name);
 581  
 582              if ($method instanceof \phpbb\notification\method\method_interface)
 583              {
 584                  $subscription_methods[$method_name] = $method;
 585              }
 586          }
 587  
 588          return $subscription_methods;
 589      }
 590  
 591      /**
 592      * Get all of the available subscription methods
 593      *
 594      * @return array Array of method's instances
 595      */
 596  	private function get_available_subscription_methods()
 597      {
 598          $subscription_methods = array();
 599  
 600          /** @var method\method_interface $method */
 601          foreach ($this->get_subscription_methods_instances() as $method_name => $method)
 602          {
 603              if ($method->is_available())
 604              {
 605                  $subscription_methods[$method_name] = $method;
 606              }
 607          }
 608  
 609          return $subscription_methods;
 610      }
 611  
 612  
 613      /**
 614      * Get user's notification data
 615      *
 616      * @param int $user_id The user_id of the user to get the notifications for
 617      *
 618      * @return array User's notification
 619      */
 620  	protected function get_user_notifications($user_id)
 621      {
 622          $sql = 'SELECT method, notify, item_type
 623                  FROM ' . $this->user_notifications_table . '
 624                  WHERE user_id = ' . (int) $user_id . '
 625                      AND item_id = 0';
 626  
 627          $result = $this->db->sql_query($sql);
 628          $user_notifications = array();
 629  
 630          while ($row = $this->db->sql_fetchrow($result))
 631          {
 632              $user_notifications[$row['item_type']][] = $row;
 633          }
 634  
 635          $this->db->sql_freeresult($result);
 636  
 637          return $user_notifications;
 638      }
 639  
 640      /**
 641      * Get global subscriptions (item_id = 0)
 642      *
 643      * @param bool|int $user_id The user_id to add the subscription for (bool false for current user)
 644      *
 645      * @return array Subscriptions
 646      */
 647  	public function get_global_subscriptions($user_id = false)
 648      {
 649          $user_id = $user_id ?: $this->user->data['user_id'];
 650  
 651          $subscriptions = array();
 652          $default_methods = $this->get_default_methods();
 653  
 654          $user_notifications = $this->get_user_notifications($user_id);
 655  
 656          foreach ($this->get_subscription_types() as $types)
 657          {
 658              foreach ($types as $id => $type)
 659              {
 660                  $type_subscriptions = $default_methods;
 661                  if (!empty($user_notifications[$id]))
 662                  {
 663                      foreach ($user_notifications[$id] as $user_notification)
 664                      {
 665                          $key = array_search($user_notification['method'], $type_subscriptions, true);
 666                          if (!$user_notification['notify'])
 667                          {
 668                              if ($key !== false)
 669                              {
 670                                  unset($type_subscriptions[$key]);
 671                              }
 672  
 673                              continue;
 674                          }
 675                          else if ($key === false)
 676                          {
 677                              $type_subscriptions[] = $user_notification['method'];
 678                          }
 679                      }
 680                  }
 681  
 682                  if (!empty($type_subscriptions))
 683                  {
 684                      $subscriptions[$id] = $type_subscriptions;
 685                  }
 686              }
 687          }
 688  
 689          return $subscriptions;
 690      }
 691  
 692      /**
 693      * Add a subscription
 694      *
 695      * @param string $item_type Type identifier of the subscription
 696      * @param int $item_id The id of the item
 697      * @param string $method The method of the notification e.g. 'board', 'email', or 'jabber'
 698      *                       (if null a subscription will be added for all the defaults methods)
 699      * @param bool|int $user_id The user_id to add the subscription for (bool false for current user)
 700      */
 701  	public function add_subscription($item_type, $item_id = 0, $method = null, $user_id = false)
 702      {
 703          if ($method === null)
 704          {
 705              foreach ($this->get_default_methods() as $method_name)
 706              {
 707                  $this->add_subscription($item_type, $item_id, $method_name, $user_id);
 708              }
 709  
 710              return;
 711          }
 712  
 713          $user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id;
 714  
 715          $sql = 'SELECT notify
 716              FROM ' . $this->user_notifications_table . "
 717              WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
 718                  AND item_id = " . (int) $item_id . '
 719                  AND user_id = ' .(int) $user_id . "
 720                  AND method = '" . $this->db->sql_escape($method) . "'";
 721          $this->db->sql_query($sql);
 722          $current = $this->db->sql_fetchfield('notify');
 723          $this->db->sql_freeresult();
 724  
 725          if ($current === false)
 726          {
 727              $sql = 'INSERT INTO ' . $this->user_notifications_table . ' ' .
 728                  $this->db->sql_build_array('INSERT', array(
 729                      'item_type'        => $item_type,
 730                      'item_id'        => (int) $item_id,
 731                      'user_id'        => (int) $user_id,
 732                      'method'        => $method,
 733                      'notify'        => 1,
 734                  ));
 735              $this->db->sql_query($sql);
 736          }
 737          else if (!$current)
 738          {
 739              $sql = 'UPDATE ' . $this->user_notifications_table . "
 740                  SET notify = 1
 741                  WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
 742                      AND item_id = " . (int) $item_id . '
 743                      AND user_id = ' .(int) $user_id . "
 744                      AND method = '" . $this->db->sql_escape($method) . "'";
 745              $this->db->sql_query($sql);
 746          }
 747      }
 748  
 749      /**
 750      * Delete a subscription
 751      *
 752      * @param string $item_type Type identifier of the subscription
 753      * @param int $item_id The id of the item
 754      * @param string $method The method of the notification e.g. 'board', 'email', or 'jabber'
 755      * @param bool|int $user_id The user_id to add the subscription for (bool false for current user)
 756      */
 757  	public function delete_subscription($item_type, $item_id = 0, $method = null, $user_id = false)
 758      {
 759          if ($method === null)
 760          {
 761              foreach ($this->get_default_methods() as $method_name)
 762              {
 763                  $this->delete_subscription($item_type, $item_id, $method_name, $user_id);
 764              }
 765  
 766              return;
 767          }
 768  
 769          $user_id = $user_id ?: $this->user->data['user_id'];
 770  
 771          $sql = 'UPDATE ' . $this->user_notifications_table . "
 772              SET notify = 0
 773              WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
 774                  AND item_id = " . (int) $item_id . '
 775                  AND user_id = ' .(int) $user_id . "
 776                  AND method = '" . $this->db->sql_escape($method) . "'";
 777          $this->db->sql_query($sql);
 778  
 779          if (!$this->db->sql_affectedrows())
 780          {
 781              $sql = 'INSERT INTO ' . $this->user_notifications_table . ' ' .
 782                  $this->db->sql_build_array('INSERT', array(
 783                      'item_type'        => $item_type,
 784                      'item_id'        => (int) $item_id,
 785                      'user_id'        => (int) $user_id,
 786                      'method'        => $method,
 787                      'notify'        => 0,
 788                  ));
 789              $this->db->sql_query($sql);
 790          }
 791      }
 792  
 793      /**
 794      * Disable all notifications of a certain type
 795      *
 796      * This should be called when an extension which has notification types
 797      * is disabled so that all those notifications are hidden and do not
 798      * cause errors
 799      *
 800      * @param string $notification_type_name Type identifier of the subscription
 801      */
 802  	public function disable_notifications($notification_type_name)
 803      {
 804          $sql = 'UPDATE ' . $this->notification_types_table . "
 805              SET notification_type_enabled = 0
 806              WHERE notification_type_name = '" . $this->db->sql_escape($notification_type_name) . "'";
 807          $this->db->sql_query($sql);
 808      }
 809  
 810      /**
 811      * Purge all notifications of a certain type
 812      *
 813      * This should be called when an extension which has notification types
 814      * is purged so that all those notifications are removed
 815      *
 816      * @param string $notification_type_name Type identifier of the subscription
 817      */
 818  	public function purge_notifications($notification_type_name)
 819      {
 820          // If a notification is never used, its type will not be added to the database
 821          // nor its id cached. If this method is called by an extension during the
 822          // purge step, and that extension never used its notifications,
 823          // get_notification_type_id() will throw an exception. However,
 824          // because no notification type was added to the database,
 825          // there is nothing to delete, so we can silently drop the exception.
 826          try
 827          {
 828              $notification_type_id = $this->get_notification_type_id($notification_type_name);
 829  
 830              /** @var method\method_interface $method */
 831              foreach ($this->get_available_subscription_methods() as $method)
 832              {
 833                  $method->purge_notifications($notification_type_id);
 834              }
 835  
 836          }
 837          catch (\phpbb\notification\exception $e)
 838          {
 839              // Continue
 840          }
 841      }
 842  
 843      /**
 844      * Enable all notifications of a certain type
 845      *
 846      * This should be called when an extension which has notification types
 847      * that was disabled is re-enabled so that all those notifications that
 848      * were hidden are shown again
 849      *
 850      * @param string $notification_type_name Type identifier of the subscription
 851      */
 852  	public function enable_notifications($notification_type_name)
 853      {
 854          $sql = 'UPDATE ' . $this->notification_types_table . "
 855              SET notification_type_enabled = 1
 856              WHERE notification_type_name = '" . $this->db->sql_escape($notification_type_name) . "'";
 857          $this->db->sql_query($sql);
 858      }
 859  
 860      /**
 861      * Delete all notifications older than a certain time
 862      *
 863      * @param int $timestamp Unix timestamp to delete all notifications that were created before
 864      * @param bool $only_read True (default) to only prune read notifications
 865      */
 866  	public function prune_notifications($timestamp, $only_read = true)
 867      {
 868          /** @var method\method_interface $method */
 869          foreach ($this->get_available_subscription_methods() as $method)
 870          {
 871              $method->prune_notifications($timestamp, $only_read);
 872          }
 873      }
 874  
 875      /**
 876       * Helper to get the list of methods enabled by default
 877       *
 878       * @return method\method_interface[]
 879       */
 880  	public function get_default_methods()
 881      {
 882          $default_methods = array();
 883  
 884          foreach ($this->notification_methods as $method)
 885          {
 886              if ($method->is_enabled_by_default() && $method->is_available())
 887              {
 888                  $default_methods[] = $method->get_type();
 889              }
 890          }
 891  
 892          return $default_methods;
 893      }
 894  
 895      /**
 896       * Helper to get the notifications item type class and set it up
 897       *
 898       * @param string $notification_type_name
 899       * @param array  $data
 900       * @return type\type_interface
 901       */
 902  	public function get_item_type_class($notification_type_name, $data = array())
 903      {
 904          $item = $this->load_object($notification_type_name);
 905  
 906          $item->set_initial_data($data);
 907  
 908          return $item;
 909      }
 910  
 911      /**
 912       * Helper to get the notifications method class and set it up
 913       *
 914       * @param string $method_name
 915       * @return method\method_interface
 916       */
 917  	public function get_method_class($method_name)
 918      {
 919          return $this->load_object($method_name);
 920      }
 921  
 922      /**
 923       * Helper to load objects (notification types/methods)
 924       *
 925       * @param string $object_name
 926       * @return method\method_interface|type\type_interface
 927       */
 928  	protected function load_object($object_name)
 929      {
 930          $object = $this->phpbb_container->get($object_name);
 931  
 932          if (method_exists($object, 'set_notification_manager'))
 933          {
 934              $object->set_notification_manager($this);
 935          }
 936  
 937          return $object;
 938      }
 939  
 940      /**
 941      * Get the notification type id from the name
 942      *
 943      * @param string $notification_type_name The name
 944      * @return int the notification_type_id
 945      * @throws \phpbb\notification\exception
 946      */
 947  	public function get_notification_type_id($notification_type_name)
 948      {
 949          $sql = 'SELECT notification_type_id, notification_type_name
 950              FROM ' . $this->notification_types_table;
 951          $result = $this->db->sql_query($sql, 604800); // cache for one week
 952          while ($row = $this->db->sql_fetchrow($result))
 953          {
 954              $notification_type_ids[$row['notification_type_name']] = (int) $row['notification_type_id'];
 955          }
 956          $this->db->sql_freeresult($result);
 957  
 958          if (!isset($notification_type_ids[$notification_type_name]))
 959          {
 960              if (!isset($this->notification_types[$notification_type_name]) && !isset($this->notification_types['notification.type.' . $notification_type_name]))
 961              {
 962                  throw new \phpbb\notification\exception('NOTIFICATION_TYPE_NOT_EXIST', array($notification_type_name));
 963              }
 964  
 965              $sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array(
 966                  'notification_type_name'        => $notification_type_name,
 967                  'notification_type_enabled'        => 1,
 968              ));
 969              $this->db->sql_query($sql);
 970  
 971              // expose new notification type ID for this request
 972              $notification_type_ids[$notification_type_name] = (int) $this->db->sql_nextid();
 973  
 974              // destroy cache, we have a new addition which we have to to load next time
 975              $this->cache->destroy('sql', $this->notification_types_table);
 976          }
 977  
 978          return $notification_type_ids[$notification_type_name];
 979      }
 980  
 981      /**
 982      * Get notification type ids (as an array)
 983      *
 984      * @param string|array $notification_type_names Notification type names
 985      * @return array Array of integers
 986      */
 987  	public function get_notification_type_ids($notification_type_names)
 988      {
 989          if (!is_array($notification_type_names))
 990          {
 991              $notification_type_names = array($notification_type_names);
 992          }
 993  
 994          $notification_type_ids = array();
 995  
 996          foreach ($notification_type_names as $name)
 997          {
 998              $notification_type_ids[$name] = $this->get_notification_type_id($name);
 999          }
1000  
1001          return $notification_type_ids;
1002      }
1003  
1004      /**
1005      * Find the users which are already notified
1006      *
1007      * @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
1008      * @param array $options
1009      * @return array The list of the notified users
1010      */
1011  	public function get_notified_users($notification_type_name, array $options)
1012      {
1013          $notification_type_id = $this->get_notification_type_id($notification_type_name);
1014  
1015          $notified_users = array();
1016  
1017          /** @var method\method_interface $method */
1018          foreach ($this->get_available_subscription_methods() as $method)
1019          {
1020              $notified_users = $notified_users + $method->get_notified_users($notification_type_id, $options);
1021          }
1022  
1023          return $notified_users;
1024      }
1025  }


Generated: Wed Feb 22 20:16:20 2023 Cross-referenced by PHPXref 0.7.1