[ Index ] |
PHP Cross Reference of phpBB-3.1.12-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 array */ 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\config\config */ 39 protected $config; 40 41 /** @var \phpbb\event\dispatcher_interface */ 42 protected $phpbb_dispatcher; 43 44 /** @var \phpbb\db\driver\driver_interface */ 45 protected $db; 46 47 /** @var \phpbb\cache\service */ 48 protected $cache; 49 50 /** @var \phpbb\user */ 51 protected $user; 52 53 /** @var string */ 54 protected $phpbb_root_path; 55 56 /** @var string */ 57 protected $php_ext; 58 59 /** @var string */ 60 protected $notification_types_table; 61 62 /** @var string */ 63 protected $notifications_table; 64 65 /** @var string */ 66 protected $user_notifications_table; 67 68 /** 69 * Notification Constructor 70 * 71 * @param array $notification_types 72 * @param array $notification_methods 73 * @param ContainerInterface $phpbb_container 74 * @param \phpbb\user_loader $user_loader 75 * @param \phpbb\config\config $config 76 * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher 77 * @param \phpbb\db\driver\driver_interface $db 78 * @param \phpbb\cache\service $cache 79 * @param \phpbb\user $user 80 * @param string $phpbb_root_path 81 * @param string $php_ext 82 * @param string $notification_types_table 83 * @param string $notifications_table 84 * @param string $user_notifications_table 85 * 86 * @return \phpbb\notification\manager 87 */ 88 public function __construct($notification_types, $notification_methods, ContainerInterface $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\config\config $config, \phpbb\event\dispatcher_interface $phpbb_dispatcher, \phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) 89 { 90 $this->notification_types = $notification_types; 91 $this->notification_methods = $notification_methods; 92 $this->phpbb_container = $phpbb_container; 93 94 $this->user_loader = $user_loader; 95 $this->config = $config; 96 $this->phpbb_dispatcher = $phpbb_dispatcher; 97 $this->db = $db; 98 $this->cache = $cache; 99 $this->user = $user; 100 101 $this->phpbb_root_path = $phpbb_root_path; 102 $this->php_ext = $php_ext; 103 104 $this->notification_types_table = $notification_types_table; 105 $this->notifications_table = $notifications_table; 106 $this->user_notifications_table = $user_notifications_table; 107 } 108 109 /** 110 * Load the user's notifications 111 * 112 * @param array $options Optional options to control what notifications are loaded 113 * notification_id Notification id to load (or array of notification ids) 114 * user_id User id to load notifications for (Default: $user->data['user_id']) 115 * order_by Order by (Default: notification_time) 116 * order_dir Order direction (Default: DESC) 117 * limit Number of notifications to load (Default: 5) 118 * start Notifications offset (Default: 0) 119 * all_unread Load all unread notifications? If set to true, count_unread is set to true (Default: false) 120 * count_unread Count all unread notifications? (Default: false) 121 * count_total Count all notifications? (Default: false) 122 * @return array Array of information based on the request with keys: 123 * 'notifications' array of notification type objects 124 * 'unread_count' number of unread notifications the user has if count_unread is true in the options 125 * 'total_count' number of notifications the user has if count_total is true in the options 126 */ 127 public function load_notifications(array $options = array()) 128 { 129 // Merge default options 130 $options = array_merge(array( 131 'notification_id' => false, 132 'user_id' => $this->user->data['user_id'], 133 'order_by' => 'notification_time', 134 'order_dir' => 'DESC', 135 'limit' => 0, 136 'start' => 0, 137 'all_unread' => false, 138 'count_unread' => false, 139 'count_total' => false, 140 ), $options); 141 142 // If all_unread, count_unread must be true 143 $options['count_unread'] = ($options['all_unread']) ? true : $options['count_unread']; 144 145 // Anonymous users and bots never receive notifications 146 if ($options['user_id'] == $this->user->data['user_id'] && ($this->user->data['user_id'] == ANONYMOUS || $this->user->data['user_type'] == USER_IGNORE)) 147 { 148 return array( 149 'notifications' => array(), 150 'unread_count' => 0, 151 'total_count' => 0, 152 ); 153 } 154 155 $notifications = $user_ids = array(); 156 $load_special = array(); 157 $total_count = $unread_count = 0; 158 159 if ($options['count_unread']) 160 { 161 // Get the total number of unread notifications 162 $sql = 'SELECT COUNT(n.notification_id) AS unread_count 163 FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt 164 WHERE n.user_id = ' . (int) $options['user_id'] . ' 165 AND n.notification_read = 0 166 AND nt.notification_type_id = n.notification_type_id 167 AND nt.notification_type_enabled = 1'; 168 $result = $this->db->sql_query($sql); 169 $unread_count = (int) $this->db->sql_fetchfield('unread_count'); 170 $this->db->sql_freeresult($result); 171 } 172 173 if ($options['count_total']) 174 { 175 // Get the total number of notifications 176 $sql = 'SELECT COUNT(n.notification_id) AS total_count 177 FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt 178 WHERE n.user_id = ' . (int) $options['user_id'] . ' 179 AND nt.notification_type_id = n.notification_type_id 180 AND nt.notification_type_enabled = 1'; 181 $result = $this->db->sql_query($sql); 182 $total_count = (int) $this->db->sql_fetchfield('total_count'); 183 $this->db->sql_freeresult($result); 184 } 185 186 if (!$options['count_total'] || $total_count) 187 { 188 $rowset = array(); 189 $selected_unread_count = 0; 190 191 // Get the main notifications 192 $sql = 'SELECT n.*, nt.notification_type_name 193 FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt 194 WHERE n.user_id = ' . (int) $options['user_id'] . 195 (($options['notification_id']) ? ' AND ' . $this->db->sql_in_set('n.notification_id', $options['notification_id']) : '') . ' 196 AND nt.notification_type_id = n.notification_type_id 197 AND nt.notification_type_enabled = 1 198 ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']); 199 $result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']); 200 201 while ($row = $this->db->sql_fetchrow($result)) 202 { 203 $rowset[$row['notification_id']] = $row; 204 $selected_unread_count += (int) !$row['notification_read']; 205 } 206 $this->db->sql_freeresult($result); 207 208 // Get all unread notifications 209 if ($selected_unread_count < $unread_count && $options['all_unread'] && !empty($rowset)) 210 { 211 $sql = 'SELECT n.*, nt.notification_type_name 212 FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt 213 WHERE n.user_id = ' . (int) $options['user_id'] . ' 214 AND n.notification_read = 0 215 AND ' . $this->db->sql_in_set('n.notification_id', array_keys($rowset), true) . ' 216 AND nt.notification_type_id = n.notification_type_id 217 AND nt.notification_type_enabled = 1 218 ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']); 219 $result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']); 220 221 while ($row = $this->db->sql_fetchrow($result)) 222 { 223 $rowset[$row['notification_id']] = $row; 224 } 225 $this->db->sql_freeresult($result); 226 } 227 228 foreach ($rowset as $row) 229 { 230 $notification = $this->get_item_type_class($row['notification_type_name'], $row); 231 232 // Array of user_ids to query all at once 233 $user_ids = array_merge($user_ids, $notification->users_to_query()); 234 235 // Some notification types also require querying additional tables themselves 236 if (!isset($load_special[$row['notification_type_name']])) 237 { 238 $load_special[$row['notification_type_name']] = array(); 239 } 240 $load_special[$row['notification_type_name']] = array_merge($load_special[$row['notification_type_name']], $notification->get_load_special()); 241 242 $notifications[$row['notification_id']] = $notification; 243 } 244 245 $this->user_loader->load_users($user_ids); 246 247 // Allow each type to load its own special items 248 foreach ($load_special as $item_type => $data) 249 { 250 $item_class = $this->get_item_type_class($item_type); 251 252 $item_class->load_special($data, $notifications); 253 } 254 } 255 256 return array( 257 'notifications' => $notifications, 258 'unread_count' => $unread_count, 259 'total_count' => $total_count, 260 ); 261 } 262 263 /** 264 * Mark notifications read 265 * 266 * @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 267 * @param bool|int|array $item_id Item id or array of item ids. False to mark read for all item ids 268 * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids 269 * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False) 270 */ 271 public function mark_notifications_read($notification_type_name, $item_id, $user_id, $time = false) 272 { 273 $time = ($time !== false) ? $time : time(); 274 275 $sql = 'UPDATE ' . $this->notifications_table . " 276 SET notification_read = 1 277 WHERE notification_time <= " . (int) $time . 278 (($notification_type_name !== false) ? ' AND ' . $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : '') . 279 (($user_id !== false) ? ' AND ' . $this->db->sql_in_set('user_id', $user_id) : '') . 280 (($item_id !== false) ? ' AND ' . $this->db->sql_in_set('item_id', $item_id) : ''); 281 $this->db->sql_query($sql); 282 } 283 284 /** 285 * Mark notifications read from a parent identifier 286 * 287 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types) 288 * @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 289 * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids 290 * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False) 291 */ 292 public function mark_notifications_read_by_parent($notification_type_name, $item_parent_id, $user_id, $time = false) 293 { 294 $time = ($time !== false) ? $time : time(); 295 296 $sql = 'UPDATE ' . $this->notifications_table . " 297 SET notification_read = 1 298 WHERE notification_time <= " . (int) $time . 299 (($notification_type_name !== false) ? ' AND ' . $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : '') . 300 (($item_parent_id !== false) ? ' AND ' . $this->db->sql_in_set('item_parent_id', $item_parent_id, false, true) : '') . 301 (($user_id !== false) ? ' AND ' . $this->db->sql_in_set('user_id', $user_id) : ''); 302 $this->db->sql_query($sql); 303 } 304 305 /** 306 * Mark notifications read 307 * 308 * @param int|array $notification_id Notification id or array of notification ids. 309 * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False) 310 */ 311 public function mark_notifications_read_by_id($notification_id, $time = false) 312 { 313 $time = ($time !== false) ? $time : time(); 314 315 $sql = 'UPDATE ' . $this->notifications_table . " 316 SET notification_read = 1 317 WHERE notification_time <= " . (int) $time . ' 318 AND ' . $this->db->sql_in_set('notification_id', $notification_id); 319 $this->db->sql_query($sql); 320 } 321 322 /** 323 * Add a notification 324 * 325 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types) 326 * Note: If you send an array of types, any user who could receive multiple notifications from this single item will only receive 327 * a single notification. If they MUST receive multiple notifications, call this function multiple times instead of sending an array 328 * @param array $data Data specific for this type that will be inserted 329 * @param array $options Optional options to control what notifications are loaded 330 * ignore_users array of data to specify which users should not receive certain types of notifications 331 * @return array Information about what users were notified and how they were notified 332 */ 333 public function add_notifications($notification_type_name, $data, array $options = array()) 334 { 335 $options = array_merge(array( 336 'ignore_users' => array(), 337 ), $options); 338 339 if (is_array($notification_type_name)) 340 { 341 $notified_users = array(); 342 $temp_options = $options; 343 344 foreach ($notification_type_name as $type) 345 { 346 $temp_options['ignore_users'] = $options['ignore_users'] + $notified_users; 347 $notified_users += $this->add_notifications($type, $data, $temp_options); 348 } 349 350 return $notified_users; 351 } 352 353 $item_id = $this->get_item_type_class($notification_type_name)->get_item_id($data); 354 355 // find out which users want to receive this type of notification 356 $notify_users = $this->get_item_type_class($notification_type_name)->find_users_for_notification($data, $options); 357 358 /** 359 * Allow filtering the notify_users array for a notification that is about to be sent. 360 * Here, $notify_users is already filtered by f_read and the ignored list included in the options variable 361 * 362 * @event core.notification_manager_add_notifications 363 * @var string notification_type_name The forum id from where the topic belongs 364 * @var array data Data specific for the notification_type_name used will be inserted 365 * @var array notify_users The array of userid that are going to be notified for this notification. Set to array() to cancel. 366 * @var array options The options that were used when this method was called (read only) 367 * 368 * @since 3.1.3-RC1 369 */ 370 $vars = array( 371 'notification_type_name', 372 'data', 373 'notify_users', 374 'options', 375 ); 376 extract($this->phpbb_dispatcher->trigger_event('core.notification_manager_add_notifications', compact($vars))); 377 378 $this->add_notifications_for_users($notification_type_name, $data, $notify_users); 379 380 return $notify_users; 381 } 382 383 /** 384 * Add a notification for specific users 385 * 386 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types) 387 * @param array $data Data specific for this type that will be inserted 388 * @param array $notify_users User list to notify 389 */ 390 public function add_notifications_for_users($notification_type_name, $data, $notify_users) 391 { 392 if (is_array($notification_type_name)) 393 { 394 foreach ($notification_type_name as $type) 395 { 396 $this->add_notifications_for_users($type, $data, $notify_users); 397 } 398 399 return; 400 } 401 402 $notification_type_id = $this->get_notification_type_id($notification_type_name); 403 404 $item_id = $this->get_item_type_class($notification_type_name)->get_item_id($data); 405 406 $user_ids = array(); 407 $notification_objects = $notification_methods = array(); 408 409 // Never send notifications to the anonymous user! 410 unset($notify_users[ANONYMOUS]); 411 412 // Make sure not to send new notifications to users who've already been notified about this item 413 // This may happen when an item was added, but now new users are able to see the item 414 $sql = 'SELECT n.user_id 415 FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt 416 WHERE n.notification_type_id = ' . (int) $notification_type_id . ' 417 AND n.item_id = ' . (int) $item_id . ' 418 AND nt.notification_type_id = n.notification_type_id 419 AND nt.notification_type_enabled = 1'; 420 $result = $this->db->sql_query($sql); 421 while ($row = $this->db->sql_fetchrow($result)) 422 { 423 unset($notify_users[$row['user_id']]); 424 } 425 $this->db->sql_freeresult($result); 426 427 if (!sizeof($notify_users)) 428 { 429 return; 430 } 431 432 // Allow notifications to perform actions before creating the insert array (such as run a query to cache some data needed for all notifications) 433 $notification = $this->get_item_type_class($notification_type_name); 434 $pre_create_data = $notification->pre_create_insert_array($data, $notify_users); 435 unset($notification); 436 437 $insert_buffer = new \phpbb\db\sql_insert_buffer($this->db, $this->notifications_table); 438 439 // Go through each user so we can insert a row in the DB and then notify them by their desired means 440 foreach ($notify_users as $user => $methods) 441 { 442 $notification = $this->get_item_type_class($notification_type_name); 443 444 $notification->user_id = (int) $user; 445 446 // Insert notification row using buffer. 447 $insert_buffer->insert($notification->create_insert_array($data, $pre_create_data)); 448 449 // Users are needed to send notifications 450 $user_ids = array_merge($user_ids, $notification->users_to_query()); 451 452 foreach ($methods as $method) 453 { 454 // setup the notification methods and add the notification to the queue 455 if ($method) // blank means we just insert it as a notification, but do not notify them by any other means 456 { 457 if (!isset($notification_methods[$method])) 458 { 459 $notification_methods[$method] = $this->get_method_class($method); 460 } 461 462 $notification_methods[$method]->add_to_queue($notification); 463 } 464 } 465 } 466 467 $insert_buffer->flush(); 468 469 // We need to load all of the users to send notifications 470 $this->user_loader->load_users($user_ids); 471 472 // run the queue for each method to send notifications 473 foreach ($notification_methods as $method) 474 { 475 $method->notify(); 476 } 477 } 478 479 /** 480 * Update a notification 481 * 482 * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types) 483 * @param array $data Data specific for this type that will be updated 484 */ 485 public function update_notifications($notification_type_name, $data) 486 { 487 if (is_array($notification_type_name)) 488 { 489 foreach ($notification_type_name as $type) 490 { 491 $this->update_notifications($type, $data); 492 } 493 494 return; 495 } 496 497 $notification = $this->get_item_type_class($notification_type_name); 498 499 // Allow the notifications class to over-ride the update_notifications functionality 500 if (method_exists($notification, 'update_notifications')) 501 { 502 // Return False to over-ride the rest of the update 503 if ($notification->update_notifications($data) === false) 504 { 505 return; 506 } 507 } 508 509 $notification_type_id = $this->get_notification_type_id($notification_type_name); 510 $item_id = $notification->get_item_id($data); 511 $update_array = $notification->create_update_array($data); 512 513 $sql = 'UPDATE ' . $this->notifications_table . ' 514 SET ' . $this->db->sql_build_array('UPDATE', $update_array) . ' 515 WHERE notification_type_id = ' . (int) $notification_type_id . ' 516 AND item_id = ' . (int) $item_id; 517 $this->db->sql_query($sql); 518 } 519 520 /** 521 * Delete a notification 522 * 523 * @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) 524 * @param int|array $item_id Identifier within the type (or array of ids) 525 * @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) 526 */ 527 public function delete_notifications($notification_type_name, $item_id, $parent_id = false) 528 { 529 if (is_array($notification_type_name)) 530 { 531 foreach ($notification_type_name as $type) 532 { 533 $this->delete_notifications($type, $item_id, $parent_id); 534 } 535 536 return; 537 } 538 539 $notification_type_id = $this->get_notification_type_id($notification_type_name); 540 541 $sql = 'DELETE FROM ' . $this->notifications_table . ' 542 WHERE notification_type_id = ' . (int) $notification_type_id . ' 543 AND ' . $this->db->sql_in_set('item_id', $item_id) . 544 (($parent_id !== false) ? ' AND ' . $this->db->sql_in_set('item_parent_id', $parent_id) : ''); 545 $this->db->sql_query($sql); 546 } 547 548 /** 549 * Get all of the subscription types 550 * 551 * @return array Array of item types 552 */ 553 public function get_subscription_types() 554 { 555 if ($this->subscription_types === null) 556 { 557 $this->subscription_types = array(); 558 559 foreach ($this->notification_types as $type_name => $data) 560 { 561 $type = $this->get_item_type_class($type_name); 562 563 if ($type instanceof \phpbb\notification\type\type_interface && $type->is_available()) 564 { 565 $options = array_merge(array( 566 'id' => $type->get_type(), 567 'lang' => 'NOTIFICATION_TYPE_' . strtoupper($type->get_type()), 568 'group' => 'NOTIFICATION_GROUP_MISCELLANEOUS', 569 ), (($type::$notification_option !== false) ? $type::$notification_option : array())); 570 571 $this->subscription_types[$options['group']][$options['id']] = $options; 572 } 573 } 574 575 // Move Miscellaneous to the very last section 576 if (isset($this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS'])) 577 { 578 $miscellaneous = $this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS']; 579 unset($this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS']); 580 $this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS'] = $miscellaneous; 581 } 582 } 583 584 return $this->subscription_types; 585 } 586 587 /** 588 * Get all of the subscription methods 589 * 590 * @return array Array of methods 591 */ 592 public function get_subscription_methods() 593 { 594 $subscription_methods = array(); 595 596 foreach ($this->notification_methods as $method_name => $data) 597 { 598 $method = $this->get_method_class($method_name); 599 600 if ($method instanceof \phpbb\notification\method\method_interface && $method->is_available()) 601 { 602 $subscription_methods[$method_name] = array( 603 'id' => $method->get_type(), 604 'lang' => str_replace('.', '_', strtoupper($method->get_type())), 605 ); 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 === false) ? $this->user->data['user_id'] : $user_id; 650 651 $subscriptions = array(); 652 653 $user_notifications = $this->get_user_notifications($user_id); 654 655 foreach ($this->get_subscription_types() as $types) 656 { 657 foreach ($types as $id => $type) 658 { 659 660 if (empty($user_notifications[$id])) 661 { 662 // No rows at all, default to '' 663 $subscriptions[$id] = array(''); 664 } 665 else 666 { 667 foreach ($user_notifications[$id] as $user_notification) 668 { 669 if (!$user_notification['notify']) 670 { 671 continue; 672 } 673 674 if (!isset($subscriptions[$id])) 675 { 676 $subscriptions[$id] = array(); 677 } 678 679 $subscriptions[$id][] = $user_notification['method']; 680 } 681 } 682 } 683 } 684 685 return $subscriptions; 686 } 687 688 /** 689 * Add a subscription 690 * 691 * @param string $item_type Type identifier of the subscription 692 * @param int $item_id The id of the item 693 * @param string $method The method of the notification e.g. '', 'email', or 'jabber' 694 * @param bool|int $user_id The user_id to add the subscription for (bool false for current user) 695 */ 696 public function add_subscription($item_type, $item_id = 0, $method = '', $user_id = false) 697 { 698 if ($method !== '') 699 { 700 // Make sure to subscribe them to the base subscription 701 $this->add_subscription($item_type, $item_id, '', $user_id); 702 } 703 704 $user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id; 705 706 $sql = 'SELECT notify 707 FROM ' . $this->user_notifications_table . " 708 WHERE item_type = '" . $this->db->sql_escape($item_type) . "' 709 AND item_id = " . (int) $item_id . ' 710 AND user_id = ' .(int) $user_id . " 711 AND method = '" . $this->db->sql_escape($method) . "'"; 712 $this->db->sql_query($sql); 713 $current = $this->db->sql_fetchfield('notify'); 714 $this->db->sql_freeresult(); 715 716 if ($current === false) 717 { 718 $sql = 'INSERT INTO ' . $this->user_notifications_table . ' ' . 719 $this->db->sql_build_array('INSERT', array( 720 'item_type' => $item_type, 721 'item_id' => (int) $item_id, 722 'user_id' => (int) $user_id, 723 'method' => $method, 724 'notify' => 1, 725 )); 726 $this->db->sql_query($sql); 727 } 728 else if (!$current) 729 { 730 $sql = 'UPDATE ' . $this->user_notifications_table . " 731 SET notify = 1 732 WHERE item_type = '" . $this->db->sql_escape($item_type) . "' 733 AND item_id = " . (int) $item_id . ' 734 AND user_id = ' .(int) $user_id . " 735 AND method = '" . $this->db->sql_escape($method) . "'"; 736 $this->db->sql_query($sql); 737 } 738 } 739 740 /** 741 * Delete a subscription 742 * 743 * @param string $item_type Type identifier of the subscription 744 * @param int $item_id The id of the item 745 * @param string $method The method of the notification e.g. '', 'email', or 'jabber' 746 * @param bool|int $user_id The user_id to add the subscription for (bool false for current user) 747 */ 748 public function delete_subscription($item_type, $item_id = 0, $method = '', $user_id = false) 749 { 750 $user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id; 751 752 // If no method, make sure that no other notification methods for this item are selected before deleting 753 if ($method === '') 754 { 755 $sql = 'SELECT COUNT(*) as num_notifications 756 FROM ' . $this->user_notifications_table . " 757 WHERE item_type = '" . $this->db->sql_escape($item_type) . "' 758 AND item_id = " . (int) $item_id . ' 759 AND user_id = ' .(int) $user_id . " 760 AND method <> '' 761 AND notify = 1"; 762 $this->db->sql_query($sql); 763 $num_notifications = $this->db->sql_fetchfield('num_notifications'); 764 $this->db->sql_freeresult(); 765 766 if ($num_notifications) 767 { 768 return; 769 } 770 } 771 772 $sql = 'UPDATE ' . $this->user_notifications_table . " 773 SET notify = 0 774 WHERE item_type = '" . $this->db->sql_escape($item_type) . "' 775 AND item_id = " . (int) $item_id . ' 776 AND user_id = ' .(int) $user_id . " 777 AND method = '" . $this->db->sql_escape($method) . "'"; 778 $this->db->sql_query($sql); 779 780 if (!$this->db->sql_affectedrows()) 781 { 782 $sql = 'INSERT INTO ' . $this->user_notifications_table . ' ' . 783 $this->db->sql_build_array('INSERT', array( 784 'item_type' => $item_type, 785 'item_id' => (int) $item_id, 786 'user_id' => (int) $user_id, 787 'method' => $method, 788 'notify' => 0, 789 )); 790 $this->db->sql_query($sql); 791 } 792 } 793 794 /** 795 * Disable all notifications of a certain type 796 * 797 * This should be called when an extension which has notification types 798 * is disabled so that all those notifications are hidden and do not 799 * cause errors 800 * 801 * @param string $notification_type_name Type identifier of the subscription 802 */ 803 public function disable_notifications($notification_type_name) 804 { 805 $sql = 'UPDATE ' . $this->notification_types_table . " 806 SET notification_type_enabled = 0 807 WHERE notification_type_name = '" . $this->db->sql_escape($notification_type_name) . "'"; 808 $this->db->sql_query($sql); 809 } 810 811 /** 812 * Purge all notifications of a certain type 813 * 814 * This should be called when an extension which has notification types 815 * is purged so that all those notifications are removed 816 * 817 * @param string $notification_type_name Type identifier of the subscription 818 */ 819 public function purge_notifications($notification_type_name) 820 { 821 // If a notification is never used, its type will not be added to the database 822 // nor its id cached. If this method is called by an extension during the 823 // purge step, and that extension never used its notifications, 824 // get_notification_type_id() will throw an exception. However, 825 // because no notification type was added to the database, 826 // there is nothing to delete, so we can silently drop the exception. 827 try 828 { 829 $notification_type_id = $this->get_notification_type_id($notification_type_name); 830 831 $sql = 'DELETE FROM ' . $this->notifications_table . ' 832 WHERE notification_type_id = ' . (int) $notification_type_id; 833 $this->db->sql_query($sql); 834 835 $sql = 'DELETE FROM ' . $this->notification_types_table . ' 836 WHERE notification_type_id = ' . (int) $notification_type_id; 837 $this->db->sql_query($sql); 838 839 $this->cache->destroy('notification_type_ids'); 840 } 841 catch (\phpbb\notification\exception $e) 842 { 843 // Continue 844 } 845 } 846 847 /** 848 * Enable all notifications of a certain type 849 * 850 * This should be called when an extension which has notification types 851 * that was disabled is re-enabled so that all those notifications that 852 * were hidden are shown again 853 * 854 * @param string $notification_type_name Type identifier of the subscription 855 */ 856 public function enable_notifications($notification_type_name) 857 { 858 $sql = 'UPDATE ' . $this->notification_types_table . " 859 SET notification_type_enabled = 1 860 WHERE notification_type_name = '" . $this->db->sql_escape($notification_type_name) . "'"; 861 $this->db->sql_query($sql); 862 } 863 864 /** 865 * Delete all notifications older than a certain time 866 * 867 * @param int $timestamp Unix timestamp to delete all notifications that were created before 868 * @param bool $only_read True (default) to only prune read notifications 869 */ 870 public function prune_notifications($timestamp, $only_read = true) 871 { 872 $sql = 'DELETE FROM ' . $this->notifications_table . ' 873 WHERE notification_time < ' . (int) $timestamp . 874 (($only_read) ? ' AND notification_read = 1' : ''); 875 $this->db->sql_query($sql); 876 877 $this->config->set('read_notification_last_gc', time(), false); 878 } 879 880 /** 881 * Helper to get the notifications item type class and set it up 882 */ 883 public function get_item_type_class($notification_type_name, $data = array()) 884 { 885 $item = $this->load_object($notification_type_name); 886 887 $item->set_initial_data($data); 888 889 return $item; 890 } 891 892 /** 893 * Helper to get the notifications method class and set it up 894 */ 895 public function get_method_class($method_name) 896 { 897 return $this->load_object($method_name); 898 } 899 900 /** 901 * Helper to load objects (notification types/methods) 902 */ 903 protected function load_object($object_name) 904 { 905 $object = $this->phpbb_container->get($object_name); 906 907 if (method_exists($object, 'set_notification_manager')) 908 { 909 $object->set_notification_manager($this); 910 } 911 912 return $object; 913 } 914 915 /** 916 * Get the notification type id from the name 917 * 918 * @param string $notification_type_name The name 919 * @return int the notification_type_id 920 * @throws \phpbb\notification\exception 921 */ 922 public function get_notification_type_id($notification_type_name) 923 { 924 $notification_type_ids = $this->cache->get('notification_type_ids'); 925 926 $this->db->sql_transaction('begin'); 927 928 if ($notification_type_ids === false) 929 { 930 $notification_type_ids = array(); 931 932 $sql = 'SELECT notification_type_id, notification_type_name 933 FROM ' . $this->notification_types_table; 934 $result = $this->db->sql_query($sql); 935 while ($row = $this->db->sql_fetchrow($result)) 936 { 937 $notification_type_ids[$row['notification_type_name']] = (int) $row['notification_type_id']; 938 } 939 $this->db->sql_freeresult($result); 940 941 $this->cache->put('notification_type_ids', $notification_type_ids); 942 } 943 944 if (!isset($notification_type_ids[$notification_type_name])) 945 { 946 if (!isset($this->notification_types[$notification_type_name]) && !isset($this->notification_types['notification.type.' . $notification_type_name])) 947 { 948 $this->db->sql_transaction('rollback'); 949 throw new \phpbb\notification\exception($this->user->lang('NOTIFICATION_TYPE_NOT_EXIST', $notification_type_name)); 950 } 951 952 $sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array( 953 'notification_type_name' => $notification_type_name, 954 'notification_type_enabled' => 1, 955 )); 956 $this->db->sql_query($sql); 957 958 $notification_type_ids[$notification_type_name] = (int) $this->db->sql_nextid(); 959 960 $this->cache->put('notification_type_ids', $notification_type_ids); 961 } 962 963 $this->db->sql_transaction('commit'); 964 965 return $notification_type_ids[$notification_type_name]; 966 } 967 968 /** 969 * Get notification type ids (as an array) 970 * 971 * @param string|array $notification_type_names Notification type names 972 * @return array Array of integers 973 */ 974 public function get_notification_type_ids($notification_type_names) 975 { 976 if (!is_array($notification_type_names)) 977 { 978 $notification_type_names = array($notification_type_names); 979 } 980 981 $notification_type_ids = array(); 982 983 foreach ($notification_type_names as $name) 984 { 985 $notification_type_ids[$name] = $this->get_notification_type_id($name); 986 } 987 988 return $notification_type_ids; 989 } 990 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |