[ Index ] |
PHP Cross Reference of BuddyPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * BuddyPress Messages Classes. 4 * 5 * @package BuddyPress 6 * @subpackage MessagesClasses 7 * @since 1.0.0 8 */ 9 10 // Exit if accessed directly. 11 defined( 'ABSPATH' ) || exit; 12 13 /** 14 * BuddyPress Message Thread class. 15 * 16 * @since 1.0.0 17 */ 18 class BP_Messages_Thread { 19 20 /** 21 * The message thread ID. 22 * 23 * @since 1.0.0 24 * @var int 25 */ 26 public $thread_id; 27 28 /** 29 * The current messages. 30 * 31 * @since 1.0.0 32 * @var array 33 */ 34 public $messages; 35 36 /** 37 * The current recipients in the message thread. 38 * 39 * @since 1.0.0 40 * @var array 41 */ 42 public $recipients; 43 44 /** 45 * The user IDs of all messages in the message thread. 46 * 47 * @since 1.2.0 48 * @var array 49 */ 50 public $sender_ids; 51 52 /** 53 * The unread count for the logged-in user. 54 * 55 * @since 1.2.0 56 * @var int 57 */ 58 public $unread_count; 59 60 /** 61 * The content of the last message in this thread. 62 * 63 * @since 1.2.0 64 * @var string 65 */ 66 public $last_message_content; 67 68 /** 69 * The date of the last message in this thread. 70 * 71 * @since 1.2.0 72 * @var string 73 */ 74 public $last_message_date; 75 76 /** 77 * The ID of the last message in this thread. 78 * 79 * @since 1.2.0 80 * @var int 81 */ 82 public $last_message_id; 83 84 /** 85 * The subject of the last message in this thread. 86 * 87 * @since 1.2.0 88 * @var string 89 */ 90 public $last_message_subject; 91 92 /** 93 * The user ID of the author of the last message in this thread. 94 * 95 * @since 1.2.0 96 * @var int 97 */ 98 public $last_sender_id; 99 100 /** 101 * Sort order of the messages in this thread (ASC or DESC). 102 * 103 * @since 1.5.0 104 * @var string 105 */ 106 public $messages_order; 107 108 /** 109 * Constructor. 110 * 111 * @since 1.0.0 112 * @since 10.0.0 Updated the `$args` with new paremeters. 113 * 114 * @param int $thread_id The message thread ID. 115 * @param string $order The order to sort the messages. Either 'ASC' or 'DESC'. 116 * Defaults to 'ASC'. 117 * @param array $args { 118 * Array of arguments. 119 * @type int $user_id ID of the user to get the unread count. 120 * @type bool $update_meta_cache Whether to pre-fetch metadata for 121 * queried message items. Default: true. 122 * @type int|null $page Page of messages being requested. Default to null, meaning all. 123 * @type int|null $per_page Messages to return per page. Default to null, meaning all. 124 * @type string $order Optional. The order to sort the messages. Either 'ASC' or 'DESC'. 125 * Defaults to 'ASC'. 126 * @type int|null $recipients_page Page of recipients being requested. Default to null, meaning all. 127 * @type int|null $recipients_per_page Recipients to return per page. Defaults to null, meaning all. 128 * } 129 */ 130 public function __construct( $thread_id = 0, $order = 'ASC', $args = array() ) { 131 if ( ! empty( $thread_id ) ) { 132 $this->populate( $thread_id, $order, $args ); 133 } 134 } 135 136 /** 137 * Populate method. 138 * 139 * Used in the constructor. 140 * 141 * @since 1.0.0 142 * @since 10.0.0 Updated the `$args` with new paremeters. 143 * 144 * @param int $thread_id The message thread ID. 145 * @param string $order The order to sort the messages. Either 'ASC' or 'DESC'. 146 * Defaults to 'ASC'. 147 * @param array $args { 148 * Array of arguments. 149 * @type int $user_id ID of the user to get the unread count. 150 * @type bool $update_meta_cache Whether to pre-fetch metadata for 151 * queried message items. Default: true. 152 * @type int|null $page Page of messages being requested. Default to null, meaning all. 153 * @type int|null $per_page Messages to return per page. Default to null, meaning all. 154 * @type string $order The order to sort the messages. Either 'ASC' or 'DESC'. 155 * Defaults to 'ASC'. 156 * @type int|null $recipients_page Page of recipients being requested. Default to null, meaning all. 157 * @type int|null $recipients_per_page Recipients to return per page. Defaults to null, meaning all. 158 * } 159 * @return bool False if there are no messages. 160 */ 161 public function populate( $thread_id = 0, $order = 'ASC', $args = array() ) { 162 163 $user_id = 164 bp_displayed_user_id() ? 165 bp_displayed_user_id() : 166 bp_loggedin_user_id(); 167 168 // Merge $args with our defaults. 169 $r = bp_parse_args( 170 $args, 171 array( 172 'user_id' => $user_id, 173 'update_meta_cache' => true, 174 'page' => null, 175 'per_page' => null, 176 'order' => bp_esc_sql_order( $order ), 177 'recipients_page' => null, 178 'recipients_per_page' => null, 179 ) 180 ); 181 182 $this->messages_order = $r['order']; 183 $this->thread_id = (int) $thread_id; 184 185 // Get messages for thread. 186 $this->messages = self::get_messages( $this->thread_id, $r ); 187 188 if ( empty( $this->messages ) ) { 189 return false; 190 } 191 192 $last_message_index = count( $this->messages ) - 1; 193 $this->last_message_id = $this->messages[ $last_message_index ]->id; 194 $this->last_message_date = $this->messages[ $last_message_index ]->date_sent; 195 $this->last_sender_id = $this->messages[ $last_message_index ]->sender_id; 196 $this->last_message_subject = $this->messages[ $last_message_index ]->subject; 197 $this->last_message_content = $this->messages[ $last_message_index ]->message; 198 199 foreach ( (array) $this->messages as $key => $message ) { 200 $this->sender_ids[ $message->sender_id ] = $message->sender_id; 201 } 202 203 // Fetch the recipients. 204 $this->recipients = $this->get_recipients( $thread_id, $r ); 205 206 // Get the unread count for the user. 207 if ( isset( $this->recipients[ $r['user_id'] ] ) ) { 208 $this->unread_count = $this->recipients[ $r['user_id'] ]->unread_count; 209 } 210 211 // Grab all message meta. 212 if ( true === (bool) $r['update_meta_cache'] ) { 213 bp_messages_update_meta_cache( wp_list_pluck( $this->messages, 'id' ) ); 214 } 215 216 /** 217 * Fires after a BP_Messages_Thread object has been populated. 218 * 219 * @since 2.2.0 220 * @since 10.0.0 Added `$r` as a parameter. 221 * 222 * @param BP_Messages_Thread $this Message thread object. 223 * @param array $r Array of paremeters. 224 */ 225 do_action( 'bp_messages_thread_post_populate', $this, $r ); 226 } 227 228 /** 229 * Mark a thread initialized in this class as read. 230 * 231 * @since 1.0.0 232 * 233 * @see BP_Messages_Thread::mark_as_read() 234 */ 235 public function mark_read() { 236 self::mark_as_read( $this->thread_id ); 237 } 238 239 /** 240 * Mark a thread initialized in this class as unread. 241 * 242 * @since 1.0.0 243 * 244 * @see BP_Messages_Thread::mark_as_unread() 245 */ 246 public function mark_unread() { 247 self::mark_as_unread( $this->thread_id ); 248 } 249 250 /** 251 * Returns recipients for a message thread. 252 * 253 * @since 1.0.0 254 * @since 2.3.0 Added `$thread_id` as a parameter. 255 * @since 10.0.0 Added `$args` as a parameter. 256 * 257 * @global BuddyPress $bp The one true BuddyPress instance. 258 * @global wpdb $wpdb WordPress database object. 259 * 260 * @param int $thread_id Message thread ID. 261 * @param array $args { 262 * Array of arguments. 263 * @type int|null $recipients_page Page of recipients being requested. Default to all. 264 * @type int|null $recipients_per_page Recipients to return per page. Defaults to all. 265 * } 266 * @return array 267 */ 268 public function get_recipients( $thread_id = 0, $args = array() ) { 269 global $wpdb; 270 271 if ( empty( $thread_id ) ) { 272 $thread_id = $this->thread_id; 273 } 274 275 $thread_id = (int) $thread_id; 276 277 if ( empty( $thread_id ) ) { 278 return array(); 279 } 280 281 $bp = buddypress(); 282 $r = bp_parse_args( 283 $args, 284 array( 285 'recipients_page' => null, 286 'recipients_per_page' => null, 287 ) 288 ); 289 290 // Get recipients from cache if available. 291 $recipients = wp_cache_get( 'thread_recipients_' . $thread_id, 'bp_messages' ); 292 293 // Get recipients and cache it. 294 if ( empty( $recipients ) ) { 295 296 // Query recipients. 297 $results = $wpdb->get_results( 298 $wpdb->prepare( 299 "SELECT * FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d", 300 $thread_id 301 ) 302 ); 303 304 $recipients = array(); 305 foreach ( (array) $results as $recipient ) { 306 $recipient_properties = get_object_vars( $recipient ); 307 $recipients[ $recipient->user_id ] = (object) array_map( 'intval', $recipient_properties ); 308 } 309 310 // Cache recipients. 311 wp_cache_set( 'thread_recipients_' . $thread_id, (array) $recipients, 'bp_messages' ); 312 } 313 314 // Paginate the results. 315 if ( ! empty( $recipients ) && $r['recipients_per_page'] && $r['recipients_page'] ) { 316 $start = ( $r['recipients_page'] - 1 ) * ( $r['recipients_per_page'] ); 317 $recipients = array_slice( $recipients, $start, $r['recipients_per_page'] ); 318 } 319 320 /** 321 * Filters the recipients of a message thread. 322 * 323 * @since 2.2.0 324 * @since 10.0.0 Added `$r` as a parameter. 325 * 326 * @param array $recipients Array of recipient objects. 327 * @param int $thread_id ID of the thread. 328 * @param array $r An array of parameters. 329 */ 330 return apply_filters( 'bp_messages_thread_get_recipients', (array) $recipients, (int) $thread_id, (array) $r ); 331 } 332 333 /** Static Functions ******************************************************/ 334 335 /** 336 * Get messages associated with a thread. 337 * 338 * @since 2.3.0 339 * @since 10.0.0 Added `$args` as a parameter. 340 * 341 * @global BuddyPress $bp The one true BuddyPress instance. 342 * @global wpdb $wpdb WordPress database object. 343 * 344 * @param int $thread_id The message thread ID. 345 * @param array $args { 346 * Array of arguments. 347 * @type int|null $page Page of messages being requested. Default to all. 348 * @type int|null $per_page Messages to return per page. Default to all. 349 * @type string $order The order to sort the messages. Either 'ASC' or 'DESC'. 350 * Defaults to 'ASC'. 351 * } 352 * @return array 353 */ 354 public static function get_messages( $thread_id = 0, $args = array() ) { 355 global $wpdb; 356 357 $thread_id = (int) $thread_id; 358 if ( empty( $thread_id ) ) { 359 return array(); 360 } 361 362 $bp = buddypress(); 363 $r = bp_parse_args( 364 $args, 365 array( 366 'page' => null, 367 'per_page' => null, 368 'order' => 'ASC', 369 ) 370 ); 371 372 // Sanitize 'order'. 373 $r['order'] = bp_esc_sql_order( $r['order'] ); 374 375 // Get messages from cache if available. 376 $messages = wp_cache_get( $thread_id, 'bp_messages_threads' ); 377 378 // Get messages and cache it. 379 if ( empty( $messages ) ) { 380 381 // Query messages. 382 $messages = $wpdb->get_results( 383 $wpdb->prepare( 384 "SELECT * FROM {$bp->messages->table_name_messages} WHERE thread_id = %d ORDER BY date_sent ASC", 385 $thread_id 386 ) 387 ); 388 389 foreach ( $messages as $key => $data ) { 390 $messages[ $key ]->id = (int) $messages[ $key ]->id; 391 $messages[ $key ]->thread_id = (int) $messages[ $key ]->thread_id; 392 $messages[ $key ]->sender_id = (int) $messages[ $key ]->sender_id; 393 } 394 395 // Cache messages. 396 wp_cache_set( $thread_id, (array) $messages, 'bp_messages_threads' ); 397 } 398 399 // Flip if order is DESC. 400 if ( 'DESC' === $r['order'] ) { 401 $messages = array_reverse( $messages ); 402 } 403 404 // Paginate the results. 405 if ( ! empty( $messages ) && $r['per_page'] && $r['page'] ) { 406 $start = ( $r['page'] - 1 ) * ( $r['per_page'] ); 407 $messages = array_slice( $messages, $start, $r['per_page'] ); 408 } 409 410 /** 411 * Filters the messages associated with a thread. 412 * 413 * @since 10.0.0 414 * 415 * @param array $messages Array of message objects. 416 * @param int $thread_id ID of the thread. 417 * @param array $r An array of parameters. 418 */ 419 return apply_filters( 'bp_messages_thread_get_messages', (array) $messages, (int) $thread_id, (array) $r ); 420 } 421 422 /** 423 * Static method to get message recipients by thread ID. 424 * 425 * @since 2.3.0 426 * 427 * @param int $thread_id The thread ID. 428 * @return array 429 */ 430 public static function get_recipients_for_thread( $thread_id = 0 ) { 431 $thread = new self( false ); 432 return $thread->get_recipients( $thread_id ); 433 } 434 435 /** 436 * Mark messages in a thread as deleted or delete all messages in a thread. 437 * 438 * Note: All messages in a thread are deleted once every recipient in a thread 439 * has marked the thread as deleted. 440 * 441 * @since 1.0.0 442 * @since 2.7.0 The $user_id parameter was added. Previously the current user 443 * was always assumed. 444 * 445 * @global BuddyPress $bp The one true BuddyPress instance. 446 * @global wpdb $wpdb WordPress database object. 447 * 448 * @param int $thread_id The message thread ID. 449 * @param int $user_id The ID of the user in the thread to mark messages as 450 * deleted for. Defaults to the current logged-in user. 451 * 452 * @return bool 453 */ 454 public static function delete( $thread_id = 0, $user_id = 0 ) { 455 global $wpdb; 456 457 $thread_id = (int) $thread_id; 458 $user_id = (int) $user_id; 459 460 if ( empty( $user_id ) ) { 461 $user_id = bp_loggedin_user_id(); 462 } 463 464 /** 465 * Fires before a message thread is marked as deleted. 466 * 467 * @since 2.2.0 468 * @since 2.7.0 The $user_id parameter was added. 469 * 470 * @param int $thread_id ID of the thread being deleted. 471 * @param int $user_id ID of the user that the thread is being deleted for. 472 */ 473 do_action( 'bp_messages_thread_before_mark_delete', $thread_id, $user_id ); 474 475 $bp = buddypress(); 476 477 // Mark messages as deleted 478 $wpdb->query( $wpdb->prepare( "UPDATE {$bp->messages->table_name_recipients} SET is_deleted = 1 WHERE thread_id = %d AND user_id = %d", $thread_id, $user_id ) ); 479 480 // Get the message ids in order to pass to the action. 481 $message_ids = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$bp->messages->table_name_messages} WHERE thread_id = %d", $thread_id ) ); 482 483 // Check to see if any more recipients remain for this message. 484 $recipients = $wpdb->get_results( $wpdb->prepare( "SELECT id FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d AND is_deleted = 0", $thread_id ) ); 485 486 // No more recipients so delete all messages associated with the thread. 487 if ( empty( $recipients ) ) { 488 489 /** 490 * Fires before an entire message thread is deleted. 491 * 492 * @since 2.2.0 493 * 494 * @param int $thread_id ID of the thread being deleted. 495 * @param array $message_ids IDs of messages being deleted. 496 */ 497 do_action( 'bp_messages_thread_before_delete', $thread_id, $message_ids ); 498 499 // Delete all the messages. 500 $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->messages->table_name_messages} WHERE thread_id = %d", $thread_id ) ); 501 502 // Do something for each message ID. 503 foreach ( $message_ids as $message_id ) { 504 505 // Delete message meta. 506 bp_messages_delete_meta( $message_id ); 507 508 /** 509 * Fires after a message is deleted. This hook is poorly named. 510 * 511 * @since 1.0.0 512 * 513 * @param int $message_id ID of the message. 514 */ 515 do_action( 'messages_thread_deleted_thread', $message_id ); 516 } 517 518 // Delete all the recipients. 519 $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d", $thread_id ) ); 520 } 521 522 /** 523 * Fires after a message thread is either marked as deleted or deleted. 524 * 525 * @since 2.2.0 526 * @since 2.7.0 The $user_id parameter was added. 527 * 528 * @param int $thread_id ID of the thread being deleted. 529 * @param array $message_ids IDs of messages being deleted. 530 * @param int $user_id ID of the user the threads were deleted for. 531 */ 532 do_action( 'bp_messages_thread_after_delete', $thread_id, $message_ids, $user_id ); 533 534 return true; 535 } 536 537 /** 538 * Exit a user from a thread. 539 * 540 * @since 10.0.0 541 * 542 * @global wpdb $wpdb WordPress database object. 543 * 544 * @param int $thread_id The message thread ID. 545 * @param int $user_id The ID of the user in the thread. 546 * Defaults to the current logged-in user. 547 * 548 * @return bool 549 */ 550 public static function exit_thread( $thread_id = 0, $user_id = 0 ) { 551 global $wpdb; 552 553 $thread_id = (int) $thread_id; 554 $user_id = (int) $user_id; 555 556 if ( empty( $user_id ) ) { 557 $user_id = bp_loggedin_user_id(); 558 } 559 560 // Check the user is a recipient of the thread and recipients count > 2. 561 $recipients = self::get_recipients_for_thread( $thread_id ); 562 $recipient_ids = wp_list_pluck( $recipients, 'user_id' ); 563 564 if ( 2 >= count( $recipient_ids ) || ! in_array( $user_id, $recipient_ids, true ) ) { 565 return false; 566 } 567 568 /** 569 * Fires before a user exits a thread. 570 * 571 * @since 10.0.0 572 * 573 * @param int $thread_id ID of the thread being deleted. 574 * @param int $user_id ID of the user that the thread is being deleted for. 575 */ 576 do_action( 'bp_messages_thread_before_exit', $thread_id, $user_id ); 577 578 $bp = buddypress(); 579 580 // Delete the user from messages recipients 581 $exited = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d AND user_id = %d", $thread_id, $user_id ) ); 582 583 // Bail if the user wasn't removed from the recipients list. 584 if ( empty( $exited ) ) { 585 return false; 586 } 587 588 /** 589 * Fires after a user exits a thread. 590 * 591 * @since 10.0.0 592 * 593 * @param int $thread_id ID of the thread being deleted. 594 * @param int $user_id ID of the user the threads were deleted for. 595 */ 596 do_action( 'bp_messages_thread_after_exit', $thread_id, $user_id ); 597 598 return true; 599 } 600 601 /** 602 * Get current message threads for a user. 603 * 604 * @since 1.0.0 605 * 606 * @global BuddyPress $bp The one true BuddyPress instance. 607 * @global wpdb $wpdb WordPress database object. 608 * 609 * @param array $args { 610 * Array of arguments. 611 * @type int $user_id The user ID. 612 * @type string $box The type of mailbox to get. Either 'inbox' or 'sentbox'. 613 * Defaults to 'inbox'. 614 * @type string $type The type of messages to get. Either 'all' or 'unread' 615 * or 'read'. Defaults to 'all'. 616 * @type int $limit The number of messages to get. Defaults to null. 617 * @type int $page The page number to get. Defaults to null. 618 * @type string $search_terms The search term to use. Defaults to ''. 619 * @type array $meta_query Meta query arguments. See WP_Meta_Query for more details. 620 * @type int|null $recipients_page Page of recipients being requested. Default to null, meaning all. 621 * @type int|null $recipients_per_page Recipients to return per page. Defaults to null, meaning all. 622 * @type int|null $messages_page Page of messages being requested. Default to null, meaning all. 623 * @type int|null $messages_per_page Messages to return per page. Defaults to null, meaning all. 624 * } 625 * @return array|bool Array on success. False on failure. 626 */ 627 public static function get_current_threads_for_user( $args = array() ) { 628 global $wpdb; 629 630 $function_args = func_get_args(); 631 632 // Backward compatibility with old method of passing arguments. 633 if ( ! is_array( $args ) || count( $function_args ) > 1 ) { 634 _deprecated_argument( 635 __METHOD__, 636 '2.2.0', 637 sprintf( 638 /* translators: 1: the name of the method. 2: the name of the file. */ 639 esc_html__( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), 640 __METHOD__, 641 __FILE__ 642 ) 643 ); 644 645 $old_args_keys = array( 646 0 => 'user_id', 647 1 => 'box', 648 2 => 'type', 649 3 => 'limit', 650 4 => 'page', 651 5 => 'search_terms', 652 ); 653 654 $args = bp_core_parse_args_array( $old_args_keys, $function_args ); 655 } 656 657 $r = bp_parse_args( 658 $args, 659 array( 660 'user_id' => false, 661 'box' => 'inbox', 662 'type' => 'all', 663 'limit' => null, 664 'page' => null, 665 'recipients_page' => null, 666 'recipients_per_page' => null, 667 'messages_page' => null, 668 'messages_per_page' => null, 669 'search_terms' => '', 670 'meta_query' => array(), 671 ) 672 ); 673 674 $pag_sql = $type_sql = $search_sql = $user_id_sql = $sender_sql = ''; 675 $meta_query_sql = array( 676 'join' => '', 677 'where' => '', 678 ); 679 680 if ( $r['limit'] && $r['page'] ) { 681 $pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $r['page'] - 1 ) * $r['limit'] ), intval( $r['limit'] ) ); 682 } 683 684 if ( $r['type'] == 'unread' ) { 685 $type_sql = " AND r.unread_count != 0 "; 686 } elseif ( $r['type'] == 'read' ) { 687 $type_sql = " AND r.unread_count = 0 "; 688 } 689 690 if ( ! empty( $r['search_terms'] ) ) { 691 $search_terms_like = '%' . bp_esc_like( $r['search_terms'] ) . '%'; 692 $search_sql = $wpdb->prepare( "AND ( subject LIKE %s OR message LIKE %s )", $search_terms_like, $search_terms_like ); 693 } 694 695 $r['user_id'] = (int) $r['user_id']; 696 697 // Default deleted SQL. 698 $deleted_sql = 'r.is_deleted = 0'; 699 700 switch ( $r['box'] ) { 701 case 'sentbox': 702 $user_id_sql = 'AND ' . $wpdb->prepare( 'm.sender_id = %d', $r['user_id'] ); 703 $sender_sql = 'AND m.sender_id = r.user_id'; 704 break; 705 706 case 'inbox': 707 $user_id_sql = 'AND ' . $wpdb->prepare( 'r.user_id = %d', $r['user_id'] ); 708 $sender_sql = 'AND r.sender_only = 0'; 709 break; 710 711 default: 712 // Omit user-deleted threads from all other custom message boxes. 713 $deleted_sql = $wpdb->prepare( '( r.user_id = %d AND r.is_deleted = 0 )', $r['user_id'] ); 714 break; 715 } 716 717 // Process meta query into SQL. 718 $meta_query = self::get_meta_query_sql( $r['meta_query'] ); 719 if ( ! empty( $meta_query['join'] ) ) { 720 $meta_query_sql['join'] = $meta_query['join']; 721 } 722 if ( ! empty( $meta_query['where'] ) ) { 723 $meta_query_sql['where'] = $meta_query['where']; 724 } 725 726 $bp = buddypress(); 727 728 // Set up SQL array. 729 $sql = array(); 730 $sql['select'] = 'SELECT m.thread_id, MAX(m.date_sent) AS date_sent'; 731 $sql['from'] = "FROM {$bp->messages->table_name_recipients} r INNER JOIN {$bp->messages->table_name_messages} m ON m.thread_id = r.thread_id {$meta_query_sql['join']}"; 732 $sql['where'] = "WHERE {$deleted_sql} {$user_id_sql} {$sender_sql} {$type_sql} {$search_sql} {$meta_query_sql['where']}"; 733 $sql['misc'] = "GROUP BY m.thread_id ORDER BY date_sent DESC {$pag_sql}"; 734 735 // Get thread IDs. 736 $thread_ids = $wpdb->get_results( implode( ' ', $sql ) ); 737 if ( empty( $thread_ids ) ) { 738 return false; 739 } 740 741 // Adjust $sql to work for thread total. 742 $sql['select'] = 'SELECT COUNT( DISTINCT m.thread_id )'; 743 unset( $sql['misc'] ); 744 $total_threads = $wpdb->get_var( implode( ' ', $sql ) ); 745 746 // Sort threads by date_sent. 747 foreach( (array) $thread_ids as $thread ) { 748 $sorted_threads[ $thread->thread_id ] = strtotime( $thread->date_sent ); 749 } 750 751 arsort( $sorted_threads ); 752 753 $threads = array(); 754 foreach ( (array) $sorted_threads as $thread_id => $date_sent ) { 755 $threads[] = new BP_Messages_Thread( 756 $thread_id, 757 'ASC', 758 array( 759 'update_meta_cache' => false, 760 'recipients_page' => $r['recipients_page'], 761 'recipients_per_page' => $r['recipients_per_page'], 762 'page' => $r['messages_page'], 763 'per_page' => $r['messages_per_page'], 764 ) 765 ); 766 } 767 768 /** 769 * Filters the results of the query for a user's message threads. 770 * 771 * @since 2.2.0 772 * 773 * @param array $value { 774 * @type array $threads Array of threads. Passed by reference. 775 * @type int $total_threads Number of threads found by the query. 776 * } 777 * @param array $r Array of paremeters. 778 */ 779 return apply_filters( 780 'bp_messages_thread_current_threads', 781 array( 782 'threads' => &$threads, 783 'total' => (int) $total_threads, 784 ), 785 $r 786 ); 787 } 788 789 /** 790 * Get the SQL for the 'meta_query' param in BP_Messages_Thread::get_current_threads_for_user(). 791 * 792 * We use WP_Meta_Query to do the heavy lifting of parsing the meta_query array 793 * and creating the necessary SQL clauses. 794 * 795 * @since 2.2.0 796 * 797 * @global wpdb $wpdb WordPress database object. 798 * 799 * @param array $meta_query An array of meta_query filters. See the 800 * documentation for WP_Meta_Query for details. 801 * @return array $sql_array 'join' and 'where' clauses. 802 */ 803 public static function get_meta_query_sql( $meta_query = array() ) { 804 global $wpdb; 805 806 $sql_array = array( 807 'join' => '', 808 'where' => '', 809 ); 810 811 if ( ! empty( $meta_query ) ) { 812 $meta_query = new WP_Meta_Query( $meta_query ); 813 814 // WP_Meta_Query expects the table name at 815 // $wpdb->messagemeta. 816 $wpdb->messagemeta = buddypress()->messages->table_name_meta; 817 818 return $meta_query->get_sql( 'message', 'm', 'id' ); 819 } 820 821 return $sql_array; 822 } 823 824 /** 825 * Mark a thread as read. 826 * 827 * @since 1.0.0 828 * @since 9.0.0 Added the `user_id` parameter. 829 * 830 * @global BuddyPress $bp The one true BuddyPress instance. 831 * @global wpdb $wpdb WordPress database object. 832 * 833 * @param int $thread_id The message thread ID. 834 * @param int $user_id The user the thread will be marked as read. 835 * 836 * @return bool|int Number of threads marked as read or false on error. 837 */ 838 public static function mark_as_read( $thread_id = 0, $user_id = 0 ) { 839 global $wpdb; 840 841 if ( empty( $user_id ) ) { 842 $user_id = 843 bp_displayed_user_id() ? 844 bp_displayed_user_id() : 845 bp_loggedin_user_id(); 846 } 847 848 $bp = buddypress(); 849 $num_rows = $wpdb->query( $wpdb->prepare( "UPDATE {$bp->messages->table_name_recipients} SET unread_count = 0 WHERE user_id = %d AND thread_id = %d", $user_id, $thread_id ) ); 850 851 wp_cache_delete( 'thread_recipients_' . $thread_id, 'bp_messages' ); 852 wp_cache_delete( $user_id, 'bp_messages_unread_count' ); 853 854 /** 855 * Fires when messages thread was marked as read. 856 * 857 * @since 2.8.0 858 * @since 9.0.0 Added the `user_id` parameter. 859 * @since 10.0.0 Added the `$num_rows` parameter. 860 * 861 * @param int $thread_id The message thread ID. 862 * @param int $user_id The user the thread will be marked as read. 863 * @param bool|int $num_rows Number of threads marked as unread or false on error. 864 */ 865 do_action( 'messages_thread_mark_as_read', $thread_id, $user_id, $num_rows ); 866 867 return $num_rows; 868 } 869 870 /** 871 * Mark a thread as unread. 872 * 873 * @since 1.0.0 874 * @since 9.0.0 Added the `user_id` parameter. 875 * 876 * @global BuddyPress $bp The one true BuddyPress instance. 877 * @global wpdb $wpdb WordPress database object. 878 * 879 * @param int $thread_id The message thread ID. 880 * @param int $user_id The user the thread will be marked as unread. 881 * 882 * @return bool|int Number of threads marked as unread or false on error. 883 */ 884 public static function mark_as_unread( $thread_id = 0, $user_id = 0 ) { 885 global $wpdb; 886 887 if ( empty( $user_id ) ) { 888 $user_id = 889 bp_displayed_user_id() ? 890 bp_displayed_user_id() : 891 bp_loggedin_user_id(); 892 } 893 894 $bp = buddypress(); 895 $num_rows = $wpdb->query( $wpdb->prepare( "UPDATE {$bp->messages->table_name_recipients} SET unread_count = 1 WHERE user_id = %d AND thread_id = %d", $user_id, $thread_id ) ); 896 897 wp_cache_delete( 'thread_recipients_' . $thread_id, 'bp_messages' ); 898 wp_cache_delete( $user_id, 'bp_messages_unread_count' ); 899 900 /** 901 * Fires when messages thread was marked as unread. 902 * 903 * @since 2.8.0 904 * @since 9.0.0 Added the `$user_id` parameter. 905 * @since 10.0.0 Added the `$num_rows` parameter. 906 * 907 * @param int $thread_id The message thread ID. 908 * @param int $user_id The user the thread will be marked as unread. 909 * @param bool|int $num_rows Number of threads marked as unread or false on error. 910 */ 911 do_action( 'messages_thread_mark_as_unread', $thread_id, $user_id, $num_rows ); 912 913 return $num_rows; 914 } 915 916 /** 917 * Returns the total number of message threads for a user. 918 * 919 * @since 1.0.0 920 * 921 * @param int $user_id The user ID. 922 * @param string $box The type of mailbox to get. Either 'inbox' or 'sentbox'. 923 * Defaults to 'inbox'. 924 * @param string $type The type of messages to get. Either 'all' or 'unread'. 925 * or 'read'. Defaults to 'all'. 926 * @return int Total thread count for the provided user. 927 */ 928 public static function get_total_threads_for_user( $user_id, $box = 'inbox', $type = 'all' ) { 929 global $wpdb; 930 931 $exclude_sender = $type_sql = ''; 932 if ( $box !== 'sentbox' ) { 933 $exclude_sender = 'AND sender_only != 1'; 934 } 935 936 if ( $type === 'unread' ) { 937 $type_sql = 'AND unread_count != 0'; 938 } elseif ( $type === 'read' ) { 939 $type_sql = 'AND unread_count = 0'; 940 } 941 942 $bp = buddypress(); 943 944 return (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(thread_id) FROM {$bp->messages->table_name_recipients} WHERE user_id = %d AND is_deleted = 0 {$exclude_sender} {$type_sql}", $user_id ) ); 945 } 946 947 /** 948 * Determine if the logged-in user is a sender of any message in a thread. 949 * 950 * @since 1.0.0 951 * 952 * @global BuddyPress $bp The one true BuddyPress instance. 953 * @global wpdb $wpdb WordPress database object. 954 * 955 * @param int $thread_id The message thread ID. 956 * @return bool 957 */ 958 public static function user_is_sender( $thread_id ) { 959 global $wpdb; 960 961 $bp = buddypress(); 962 963 $sender_ids = $wpdb->get_col( $wpdb->prepare( "SELECT sender_id FROM {$bp->messages->table_name_messages} WHERE thread_id = %d", $thread_id ) ); 964 965 if ( empty( $sender_ids ) ) { 966 return false; 967 } 968 969 return in_array( bp_loggedin_user_id(), $sender_ids, true ); 970 } 971 972 /** 973 * Returns the userlink of the last sender in a message thread. 974 * 975 * @since 1.0.0 976 * 977 * @global BuddyPress $bp The one true BuddyPress instance. 978 * @global wpdb $wpdb WordPress database object. 979 * 980 * @param int $thread_id The message thread ID. 981 * @return string|bool The user link on success. Boolean false on failure. 982 */ 983 public static function get_last_sender( $thread_id ) { 984 global $wpdb; 985 986 $bp = buddypress(); 987 988 if ( ! $sender_id = $wpdb->get_var( $wpdb->prepare( "SELECT sender_id FROM {$bp->messages->table_name_messages} WHERE thread_id = %d GROUP BY sender_id ORDER BY date_sent LIMIT 1", $thread_id ) ) ) { 989 return false; 990 } 991 992 return bp_core_get_userlink( $sender_id, true ); 993 } 994 995 /** 996 * Gets the unread message count for a user. 997 * 998 * @since 1.0.0 999 * 1000 * @global BuddyPress $bp The one true BuddyPress instance. 1001 * @global wpdb $wpdb WordPress database object. 1002 * 1003 * @param int $user_id The user ID. 1004 * @return int Total inbox unread count for user. 1005 */ 1006 public static function get_inbox_count( $user_id = 0 ) { 1007 global $wpdb; 1008 1009 if ( empty( $user_id ) ) { 1010 $user_id = bp_loggedin_user_id(); 1011 } 1012 1013 $unread_count = wp_cache_get( $user_id, 'bp_messages_unread_count' ); 1014 1015 if ( false === $unread_count ) { 1016 $bp = buddypress(); 1017 1018 $unread_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT SUM(unread_count) FROM {$bp->messages->table_name_recipients} WHERE user_id = %d AND is_deleted = 0 AND sender_only = 0", $user_id ) ); 1019 1020 wp_cache_set( $user_id, $unread_count, 'bp_messages_unread_count' ); 1021 } 1022 1023 /** 1024 * Filters a user's unread message count. 1025 * 1026 * @since 2.2.0 1027 * 1028 * @param int $unread_count Unread message count. 1029 * @param int $user_id ID of the user. 1030 */ 1031 return apply_filters( 'messages_thread_get_inbox_count', (int) $unread_count, $user_id ); 1032 } 1033 1034 /** 1035 * Checks whether a user is a part of a message thread discussion. 1036 * 1037 * @since 1.0.0 1038 * 1039 * @param int $thread_id The message thread ID. 1040 * @param int $user_id The user ID. Default: ID of the logged-in user. 1041 * @return int|null The recorded recipient ID on success, null on failure. 1042 */ 1043 public static function check_access( $thread_id, $user_id = 0 ) { 1044 1045 if ( empty( $user_id ) ) { 1046 $user_id = bp_loggedin_user_id(); 1047 } 1048 1049 $recipients = self::get_recipients_for_thread( $thread_id ); 1050 1051 if ( isset( $recipients[ $user_id ] ) && 0 === $recipients[ $user_id ]->is_deleted ) { 1052 return $recipients[ $user_id ]->id; 1053 } 1054 1055 return null; 1056 } 1057 1058 /** 1059 * Checks whether a message thread exists. 1060 * 1061 * @since 1.0.0 1062 * 1063 * @param int $thread_id The message thread ID. 1064 * @return bool|int|null The message thread ID on success, null on failure. 1065 */ 1066 public static function is_valid( $thread_id = 0 ) { 1067 1068 // Bail if no thread ID is passed. 1069 if ( empty( $thread_id ) ) { 1070 return false; 1071 } 1072 1073 $thread = self::get_messages( $thread_id ); 1074 1075 if ( ! empty( $thread ) ) { 1076 return $thread_id; 1077 } else { 1078 return null; 1079 } 1080 } 1081 1082 /** 1083 * Returns a string containing all the message recipient userlinks. 1084 * 1085 * String is comma-delimited. 1086 * 1087 * If a message thread has more than four users, the returned string is simply 1088 * "X Recipients" where "X" is the number of recipients in the message thread. 1089 * 1090 * @since 1.0.0 1091 * 1092 * @param array $recipients Array containing the message recipients (array of objects). 1093 * @return string String of message recipent userlinks. 1094 */ 1095 public static function get_recipient_links( $recipients ) { 1096 1097 if ( count( $recipients ) >= 5 ) { 1098 /* translators: %s: number of message recipients */ 1099 return sprintf( __( '%s Recipients', 'buddypress' ), number_format_i18n( count( $recipients ) ) ); 1100 } 1101 1102 $recipient_links = array(); 1103 1104 foreach ( (array) $recipients as $recipient ) { 1105 $recipient_link = bp_core_get_userlink( $recipient->user_id ); 1106 1107 if ( empty( $recipient_link ) ) { 1108 $recipient_link = __( 'Deleted User', 'buddypress' ); 1109 } 1110 1111 $recipient_links[] = $recipient_link; 1112 } 1113 1114 return implode( ', ', (array) $recipient_links ); 1115 } 1116 1117 /** 1118 * Upgrade method for the older BP message thread DB table. 1119 * 1120 * @todo We should remove this. No one is going to upgrade from v1.1, right? 1121 * 1122 * @since 1.2.0 1123 * 1124 * @global BuddyPress $bp The one true BuddyPress instance. 1125 * @global wpdb $wpdb WordPress database object. 1126 * 1127 * @return bool 1128 */ 1129 public static function update_tables() { 1130 global $wpdb; 1131 1132 $bp_prefix = bp_core_get_table_prefix(); 1133 $errors = false; 1134 $threads = $wpdb->get_results( "SELECT * FROM {$bp_prefix}bp_messages_threads" ); 1135 1136 // Nothing to update, just return true to remove the table. 1137 if ( empty( $threads ) ) { 1138 return true; 1139 } 1140 1141 $bp = buddypress(); 1142 1143 foreach( (array) $threads as $thread ) { 1144 $message_ids = maybe_unserialize( $thread->message_ids ); 1145 1146 if ( ! empty( $message_ids ) ) { 1147 $message_ids = implode( ',', $message_ids ); 1148 1149 // Add the thread_id to the messages table. 1150 if ( ! $wpdb->query( $wpdb->prepare( "UPDATE {$bp->messages->table_name_messages} SET thread_id = %d WHERE id IN ({$message_ids})", $thread->id ) ) ) { 1151 $errors = true; 1152 } 1153 } 1154 } 1155 1156 return (bool) ! $errors; 1157 } 1158 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:00:57 2024 | Cross-referenced by PHPXref 0.7.1 |