[ Index ] |
PHP Cross Reference of phpBB-3.3.10-deutsch |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Feb 22 20:16:20 2023 | Cross-referenced by PHPXref 0.7.1 |