[ Index ]

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


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1