[ Index ]

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


Generated: Sun Jun 23 12:25:44 2024 Cross-referenced by PHPXref 0.7.1