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