Ticket #7523: 7523.01.patch
| File 7523.01.patch, 13.9 KB (added by , 9 years ago) |
|---|
-
src/bp-messages/bp-messages-functions.php
550 550 return $retval; 551 551 } 552 552 553 /** Email *********************************************************************/ 553 /** Hooks *********************************************************************/ 554 555 /** 556 * Delete all message threads that the deleted user has sent. 557 * 558 * @since 2.9.0 559 * 560 * @param int $user_id The deleted user ID. 561 */ 562 function bp_messages_delete_threads_on_user_delete( $user_id ) { 563 $threads = BP_Messages_Thread::get_current_threads_for_user( array( 564 'user_id' => $user_id, 565 'box' => 'sentbox', 566 'deleted' => null, 567 'fields' => 'ids', 568 'count_total' => false 569 ) ); 570 571 if ( empty( $threads ) ) { 572 return; 573 } 574 575 foreach ( $threads['threads'] as $thread_id ) { 576 BP_Messages_Thread::delete( $thread_id, $user_id, true ); 577 } 578 } 579 add_action( 'deleted_user', 'bp_messages_delete_threads_on_user_delete' ); 554 580 555 581 /** 556 582 * Email message recipients to alert them of a new unread private message. -
src/bp-messages/classes/class-bp-messages-thread.php
328 328 * @since 1.0.0 329 329 * @since 2.7.0 The $user_id parameter was added. Previously the current user 330 330 * was always assumed. 331 * 332 * @param int $thread_id The message thread ID. 333 * @param int $user_id The ID of the user in the thread to mark messages as 334 * deleted for. Defaults to the current logged-in user. 335 * 331 * @since 2.9.0 Added $force as a parameter. 332 * 333 * @param int $thread_id The message thread ID. 334 * @param int $user_id The ID of the user in the thread to mark messages as deleted for. Defaults 335 * to the current logged-in user. 336 * @param bool $force Whether to delete the entire message thread for all recipients. If false, 337 * every recipient in a thread needs to mark the thread as deleted before the 338 * thread is deleted from the DB. Default: false. 336 339 * @return bool 337 340 */ 338 public static function delete( $thread_id = 0, $user_id = 0 ) {341 public static function delete( $thread_id = 0, $user_id = 0, $force = false ) { 339 342 global $wpdb; 340 343 341 $thread_id = (int) $thread_id;342 $user_id = (int) $user_id;344 $thread_id = (int) $thread_id; 345 $user_id = (int) $user_id; 343 346 344 347 if ( empty( $user_id ) ) { 345 348 $user_id = bp_loggedin_user_id(); … … 358 361 359 362 $bp = buddypress(); 360 363 361 // Mark messages as deleted362 $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 ) );363 364 364 // Get the message ids in order to pass to the action. 365 365 $message_ids = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$bp->messages->table_name_messages} WHERE thread_id = %d", $thread_id ) ); 366 366 367 // Check to see if any more recipients remain for this message. 368 $recipients = $wpdb->get_results( $wpdb->prepare( "SELECT id FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d AND is_deleted = 0", $thread_id ) ); 367 // Do the following when a user manually deletes a thread. 368 if ( false === $force ) { 369 // Mark messages as deleted 370 $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 ) ); 371 372 // Check to see if any more recipients remain for this message. 373 $recipients = $wpdb->get_results( $wpdb->prepare( "SELECT id FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d AND is_deleted = 0", $thread_id ) ); 374 } 369 375 370 376 // No more recipients so delete all messages associated with the thread. 371 if ( empty( $recipients) ) {377 if ( true === $force || ( false === $force && isset( $recipients ) && empty( $recipients ) ) ) { 372 378 373 379 /** 374 380 * Fires before an entire message thread is deleted. … … 422 428 * Get current message threads for a user. 423 429 * 424 430 * @since 1.0.0 431 * @since 2.9.0 Added $deleted, $fields and $count_total as parameters to $args. 425 432 * 426 433 * @param array $args { 427 434 * Array of arguments. 428 * @type int $user_id The user ID. 429 * @type string $box The type of mailbox to get. Either 'inbox' or 'sentbox'. 430 * Defaults to 'inbox'. 431 * @type string $type The type of messages to get. Either 'all' or 'unread' 432 * or 'read'. Defaults to 'all'. 433 * @type int $limit The number of messages to get. Defaults to null. 434 * @type int $page The page number to get. Defaults to null. 435 * @type string $search_terms The search term to use. Defaults to ''. 436 * @type array $meta_query Meta query arguments. See WP_Meta_Query for more details. 435 * @type int $user_id The user ID. 436 * @type string $box The type of mailbox to get. Either 'inbox' or 'sentbox'. 437 * Defaults to 'inbox'. 438 * @type string $type The type of messages to get. Either 'all' or 'unread' 439 * or 'read'. Defaults to 'all'. 440 * @type int $limit The number of messages to get. Defaults to null. 441 * @type int $page The page number to get. Defaults to null. 442 * @type string $search_terms The search term to use. Defaults to ''. 443 * @type array $meta_query Meta query arguments. See WP_Meta_Query for more details. 444 * @type int|null $deleted Whether to fetch deleted messages. 0 means we will not fetch deleted 445 * messages; 1 means we will. null means we will not query for deleted 446 * messages. Default: 0. 447 * @type string $fields Thread fields to retrieve. 'all' to fetch entire thread objects, 'ids' to 448 * get only the message thread IDs. DefaultL 'all'. 449 * @type bool $count_total If true, an additional DB query is run to count the total message threads 450 * for the query. Default: true. 437 451 * } 438 452 * @return array|bool Array on success. Boolean false on failure. 439 453 */ … … 463 477 'limit' => null, 464 478 'page' => null, 465 479 'search_terms' => '', 466 'meta_query' => array() 480 'meta_query' => array(), 481 'deleted' => 0, 482 'fields' => 'all', 483 'count_total' => true 467 484 ) ); 468 485 469 $pag_sql = $type_sql = $search_sql = $user_id_sql = $sender_sql = ''; 470 $meta_query_sql = array( 471 'join' => '', 472 'where' => '' 473 ); 486 $pag_sql = $meta_query_join_sql = ''; 487 $where = array(); 474 488 475 489 if ( $r['limit'] && $r['page'] ) { 476 490 $pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $r['page'] - 1 ) * $r['limit'] ), intval( $r['limit'] ) ); 477 491 } 478 492 479 493 if ( $r['type'] == 'unread' ) { 480 $ type_sql = " ANDr.unread_count != 0 ";494 $where['type'] = "r.unread_count != 0 "; 481 495 } elseif ( $r['type'] == 'read' ) { 482 $ type_sql = " ANDr.unread_count = 0 ";496 $where['type'] = "r.unread_count = 0 "; 483 497 } 484 498 485 499 if ( ! empty( $r['search_terms'] ) ) { 486 500 $search_terms_like = '%' . bp_esc_like( $r['search_terms'] ) . '%'; 487 $ search_sql = $wpdb->prepare( "AND( subject LIKE %s OR message LIKE %s )", $search_terms_like, $search_terms_like );501 $where['search'] = $wpdb->prepare( "( subject LIKE %s OR message LIKE %s )", $search_terms_like, $search_terms_like ); 488 502 } 489 503 490 504 $r['user_id'] = (int) $r['user_id']; 491 505 492 // Default deleted SQL. 493 $deleted_sql = 'r.is_deleted = 0'; 506 // Deleted SQL. 507 if ( is_int( $r['deleted'] ) ) { 508 $where['delete'] = $wpdb->prepare( "r.is_deleted = %d", $r['deleted'] ); 509 } 494 510 495 511 switch ( $r['box'] ) { 496 512 case 'sentbox' : 497 $ user_id_sql = 'AND ' .$wpdb->prepare( 'm.sender_id = %d', $r['user_id'] );498 $ sender_sql = 'ANDm.sender_id = r.user_id';513 $where['user_id'] = $wpdb->prepare( 'm.sender_id = %d', $r['user_id'] ); 514 $where['sender'] = 'm.sender_id = r.user_id'; 499 515 break; 500 516 501 517 case 'inbox' : 502 $ user_id_sql = 'AND ' .$wpdb->prepare( 'r.user_id = %d', $r['user_id'] );503 $ sender_sql = 'ANDr.sender_only = 0';518 $where['user_id'] = $wpdb->prepare( 'r.user_id = %d', $r['user_id'] ); 519 $where['sender'] = 'r.sender_only = 0'; 504 520 break; 505 521 506 522 default : 507 523 // Omit user-deleted threads from all other custom message boxes. 508 $ deleted_sql= $wpdb->prepare( '( r.user_id = %d AND r.is_deleted = 0 )', $r['user_id'] );524 $where['custom_box'] = $wpdb->prepare( '( r.user_id = %d AND r.is_deleted = 0 )', $r['user_id'] ); 509 525 break; 510 526 } 511 527 512 528 // Process meta query into SQL. 513 529 $meta_query = self::get_meta_query_sql( $r['meta_query'] ); 514 530 if ( ! empty( $meta_query['join'] ) ) { 515 $meta_query_ sql['join']= $meta_query['join'];531 $meta_query_join_sql = $meta_query['join']; 516 532 } 517 533 if ( ! empty( $meta_query['where'] ) ) { 518 $meta_query_sql['where'] = $meta_query['where']; 534 // Strips leading AND; also see BP_Groups_Group::strip_leading_and(). 535 $where['meta_query'] = preg_replace( '/^\s*AND\s*/', '', $meta_query['where'] ); 519 536 } 520 537 521 538 $bp = buddypress(); 522 539 523 540 // Set up SQL array. 524 541 $sql = array(); 525 $sql['select'] = 'SELECT m.thread_id, MAX(m.date_sent) AS date_sent'; 526 $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']}"; 527 $sql['where'] = "WHERE {$deleted_sql} {$user_id_sql} {$sender_sql} {$type_sql} {$search_sql} {$meta_query_sql['where']}"; 528 $sql['misc'] = "GROUP BY m.thread_id ORDER BY date_sent DESC {$pag_sql}"; 542 if ( 'ids' === $r['fields'] ) { 543 $sql['select'] = 'SELECT m.thread_id'; 544 } else { 545 $sql['select'] = 'SELECT m.thread_id, MAX(m.date_sent) AS date_sent'; 546 } 547 $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_join_sql}"; 548 $sql['where'] = 'WHERE ' . join( ' AND ', $where ); 549 $sql['misc'] = "GROUP BY m.thread_id ORDER BY date_sent DESC {$pag_sql}"; 529 550 530 551 // Get thread IDs. 531 $thread_ids = $wpdb->get_results( implode( ' ', $sql ) ); 552 if ( 'ids' === $r['fields'] ) { 553 $thread_ids = $wpdb->get_col( implode( ' ', $sql ) ); 554 } else { 555 $thread_ids = $wpdb->get_results( implode( ' ', $sql ) ); 556 } 532 557 if ( empty( $thread_ids ) ) { 533 558 return false; 534 559 } 535 560 536 561 // Adjust $sql to work for thread total. 537 $sql['select'] = 'SELECT COUNT( DISTINCT m.thread_id )'; 538 unset( $sql['misc'] ); 539 $total_threads = $wpdb->get_var( implode( ' ', $sql ) ); 562 $total_threads = null; 563 if ( true === $r['count_total'] ) { 564 $sql['select'] = 'SELECT COUNT( DISTINCT m.thread_id )'; 565 unset( $sql['misc'] ); 566 $total_threads = $wpdb->get_var( implode( ' ', $sql ) ); 567 } 568 569 if ( 'all' === $r['fields'] ) { 570 // Sort threads by date_sent. 571 foreach( (array) $thread_ids as $thread ) { 572 $sorted_threads[ $thread->thread_id ] = strtotime( $thread->date_sent ); 573 } 540 574 541 // Sort threads by date_sent. 542 foreach( (array) $thread_ids as $thread ) { 543 $sorted_threads[ $thread->thread_id ] = strtotime( $thread->date_sent ); 575 arsort( $sorted_threads ); 576 577 $threads = array(); 578 foreach ( (array) $sorted_threads as $thread_id => $date_sent ) { 579 $threads[] = new BP_Messages_Thread( $thread_id, 'ASC', array( 580 'update_meta_cache' => false 581 ) ); 582 } 544 583 } 545 584 546 arsort( $sorted_threads ); 585 // Set up return value. 586 if ( 'all' === $r['fields'] ) { 587 $threads = &$threads; 588 } else { 589 $threads = $thread_ids; 590 } 591 $retval = array( 'threads' => $threads ); 547 592 548 $threads = array(); 549 foreach ( (array) $sorted_threads as $thread_id => $date_sent ) { 550 $threads[] = new BP_Messages_Thread( $thread_id, 'ASC', array( 551 'update_meta_cache' => false 552 ) ); 593 if ( null !== $total_threads ) { 594 $retval['total'] = (int) $total_threads; 553 595 } 554 596 555 597 /** … … 558 600 * @since 2.2.0 559 601 * 560 602 * @param array $value { 561 * @type array $threads Array of threads. Passed by reference. 562 * @type int $total_threads Number of threads found by the query. 603 * @type array $threads Array of threads. Passed by reference if 'fields' is 'all' in the query. 604 * @type int $total_threads Number of threads found by the query. This is added as an array key if 605 * 'count_total' is true in the query. 563 606 * } 564 607 */ 565 return apply_filters( 'bp_messages_thread_current_threads', array( 566 'threads' => &$threads, 567 'total' => (int) $total_threads 568 ) ); 608 return apply_filters( 'bp_messages_thread_current_threads', $retval ); 569 609 } 570 610 571 611 /** -
tests/phpunit/testcases/messages/template.php
359 359 360 360 $_REQUEST = $request; 361 361 } 362 363 /** 364 * @group delete 365 * @group BP_Messages_Box_Template 366 */ 367 public function test_bp_messages_template_should_not_have_threads_by_deleted_user() { 368 $u1 = $this->factory->user->create(); 369 $u2 = $this->factory->user->create(); 370 $u3 = $this->factory->user->create(); 371 372 // create initial thread 373 $this->factory->message->create( array( 374 'sender_id' => $u2, 375 'recipients' => array( $u1 ), 376 ) ); 377 378 // create some threads by our deleted user 379 $this->factory->message->create_many( 3, array( 380 'sender_id' => $u3, 381 'recipients' => array( $u1 ), 382 ) ); 383 384 // Delete user 3. 385 if ( is_multisite() ) { 386 wpmu_delete_user( $u3 ); 387 } else { 388 wp_delete_user( $u3 ); 389 } 390 391 // Only the initial thread should remain. 392 $threads = new BP_Messages_Box_Template( array( 393 'user_id' => $u1 394 ) ); 395 $this->assertEquals( 1, $threads->thread_count ); 396 } 362 397 }