Ticket #7436: 7436.2.diff
File 7436.2.diff, 8.5 KB (added by , 7 years ago) |
---|
-
src/bp-core/bp-core-cache.php
diff --git a/src/bp-core/bp-core-cache.php b/src/bp-core/bp-core-cache.php index bd73b37af..5cf0d9c07 100644
a b function bp_core_set_incremented_cache( $key, $group, $ids ) { 306 306 return wp_cache_set( $cache_key, $ids, $group ); 307 307 } 308 308 309 /** 310 * Delete a value that has been cached using an incremented key. 311 * 312 * A utility function for use by query methods like BP_Activity_Activity::get(). 313 * 314 * @since 3.0.0 315 * @see bp_core_set_incremented_cache() 316 * 317 * @param string $key Unique key for the query. Usually a SQL string. 318 * @param string $group Cache group. Eg 'bp_activity'. 319 * @return bool True on successful removal, false on failure. 320 */ 321 function bp_core_delete_incremented_cache( $key, $group ) { 322 $cache_key = bp_core_get_incremented_cache_key( $key, $group ); 323 return wp_cache_delete( $cache_key, $group ); 324 } 325 309 326 /** 310 327 * Gets the key to be used when caching a value using an incremented cache key. 311 328 * -
src/bp-friends/bp-friends-cache.php
diff --git a/src/bp-friends/bp-friends-cache.php b/src/bp-friends/bp-friends-cache.php index 819f81796..67081d11e 100644
a b function bp_friends_clear_request_cache_on_remove( $friendship_id, BP_Friends_Fr 119 119 add_action( 'friends_friendship_withdrawn', 'bp_friends_clear_request_cache_on_remove', 10, 2 ); 120 120 add_action( 'friends_friendship_rejected', 'bp_friends_clear_request_cache_on_remove', 10, 2 ); 121 121 122 /** 123 * Delete individual friendships from the cache when they are changed. 124 * 125 * @since 3.0.0 126 * 127 * @param BP_Friends_Friendship $friendship Friendship object. 128 */ 129 function bp_friends_delete_cached_friendships_on_friendship_save( $friendship ) { 130 bp_core_delete_incremented_cache( $friendship->friend_user_id . ':' . $friendship->initiator_user_id, 'bp_friends' ); 131 bp_core_delete_incremented_cache( $friendship->initiator_user_id . ':' . $friendship->friend_user_id, 'bp_friends' ); 132 } 133 add_action( 'friends_friendship_after_save', 'bp_friends_delete_cached_friendships_on_friendship_save' ); 134 122 135 // List actions to clear super cached pages on, if super cache is installed. 123 136 add_action( 'friends_friendship_rejected', 'bp_core_clear_cache' ); 124 137 add_action( 'friends_friendship_accepted', 'bp_core_clear_cache' ); -
src/bp-friends/bp-friends-filters.php
diff --git a/src/bp-friends/bp-friends-filters.php b/src/bp-friends/bp-friends-filters.php index 9513b4760..cd8ffb04e 100644
a b function bp_friends_filter_user_query_populate_extras( BP_User_Query $user_query 34 34 35 35 $maybe_friend_ids = wp_parse_id_list( $user_ids_sql ); 36 36 37 // Bulk prepare the friendship cache. 38 BP_Friends_Friendship::warm_friendship_cache( $user_id, $maybe_friend_ids ); 39 37 40 foreach ( $maybe_friend_ids as $friend_id ) { 38 41 $status = BP_Friends_Friendship::check_is_friend( $user_id, $friend_id ); 39 42 $user_query->results[ $friend_id ]->friendship_status = $status; -
src/bp-friends/classes/class-bp-friends-friendship.php
diff --git a/src/bp-friends/classes/class-bp-friends-friendship.php b/src/bp-friends/classes/class-bp-friends-friendship.php index f683214e5..195b678a8 100644
a b class BP_Friends_Friendship { 603 603 return 'not_friends'; 604 604 } 605 605 606 /* 607 * Find friendships where the possible_friend_userid is the 608 * initiator or friend. 609 */ 610 $args = array( 611 'initiator_user_id' => $possible_friend_userid, 612 'friend_user_id' => $possible_friend_userid 613 ); 614 $result = self::get_friendships( $initiator_userid, $args, 'OR' ); 606 BP_Friends_Friendship::warm_friendship_cache( $initiator_userid, $possible_friend_userid ); 615 607 616 if ( $result ) { 617 $friendship = current( $result ); 618 if ( ! $friendship->is_confirmed ) { 619 $status = $initiator_userid == $friendship->initiator_user_id ? 'pending' : 'awaiting_response'; 608 return bp_core_get_incremented_cache( $initiator_userid . ':' . $possible_friend_userid, 'bp_friends' ); 609 } 610 611 612 /** 613 * Find uncached friendships between a user and one or more other users and cache them. 614 * 615 * @since 3.0.0 616 * 617 * @param int $user_id The ID of the primary user for whom we want 618 * to check friendships statuses. 619 * @param int|array|string $possible_friend_ids The IDs of the one or more users 620 * to check friendship status with primary user. 621 * @return null 622 */ 623 public static function warm_friendship_cache( $user_id, $possible_friend_ids ) { 624 global $wpdb; 625 $bp = buddypress(); 626 $possible_friend_ids = wp_parse_id_list( $possible_friend_ids ); 627 628 $fetch = array(); 629 foreach ( $possible_friend_ids as $friend_id ) { 630 // Check for cached items in both friendship directions. 631 if ( false === bp_core_get_incremented_cache( $user_id . ':' . $friend_id, 'bp_friends' ) 632 || false === bp_core_get_incremented_cache( $friend_id . ':' . $user_id, 'bp_friends' ) ) { 633 $fetch[] = $friend_id; 634 } 635 } 636 if ( empty( $fetch ) ) { 637 return; 638 } 639 640 $friend_ids_sql = implode( ',', array_unique( $fetch ) ); 641 $sql = $wpdb->prepare( "SELECT initiator_user_id, friend_user_id, is_confirmed FROM {$bp->friends->table_name} WHERE (initiator_user_id = %d AND friend_user_id IN ({$friend_ids_sql}) ) OR (initiator_user_id IN ({$friend_ids_sql}) AND friend_user_id = %d )", $user_id, $user_id ); 642 $friendships = $wpdb->get_results( $sql ); 643 644 // Use $handled to keep track of all of the $possible_friend_ids we've matched. 645 $handled = array(); 646 foreach ( $friendships as $friendship ) { 647 $initiator_user_id = (int) $friendship->initiator_user_id; 648 $friend_user_id = (int) $friendship->friend_user_id; 649 if ( 1 === (int) $friendship->is_confirmed ) { 650 $status_initiator = $status_friend = 'is_friend'; 620 651 } else { 621 $status = 'is_friend'; 652 $status_initiator = 'pending'; 653 $status_friend = 'awaiting_response'; 622 654 } 623 } else { 624 $status = 'not_friends'; 655 bp_core_set_incremented_cache( $initiator_user_id . ':' . $friend_user_id, 'bp_friends', $status_initiator ); 656 bp_core_set_incremented_cache( $friend_user_id . ':' . $initiator_user_id, 'bp_friends', $status_friend ); 657 658 $handled[] = ( $initiator_user_id === $user_id ) ? $friend_user_id : $initiator_user_id; 625 659 } 626 660 627 return $status; 661 // Set all those with no matching entry to "not friends" status. 662 $not_friends = array_diff( $fetch, $handled ); 663 664 foreach ( $not_friends as $not_friend_id ) { 665 bp_core_set_incremented_cache( $user_id . ':' . $not_friend_id, 'bp_friends', 'not_friends' ); 666 bp_core_set_incremented_cache( $not_friend_id . ':' . $user_id, 'bp_friends', 'not_friends' ); 667 } 628 668 } 629 669 630 670 /** -
tests/phpunit/testcases/friends/functions.php
diff --git a/tests/phpunit/testcases/friends/functions.php b/tests/phpunit/testcases/friends/functions.php index 2a9209090..a6f9eaa44 100644
a b class BP_Tests_Friends_Functions extends BP_UnitTestCase { 279 279 return $value; 280 280 } 281 281 282 /**283 * @group friendship_caching284 */285 public function test_friends_check_friendship_should_hit_user_cache() {286 global $wpdb;287 $now = time();288 $u1 = self::factory()->user->create( array(289 'last_activity' => date( 'Y-m-d H:i:s', $now ),290 ) );291 $u2 = self::factory()->user->create( array(292 'last_activity' => date( 'Y-m-d H:i:s', $now - 100 ),293 ) );294 $u3 = self::factory()->user->create( array(295 'last_activity' => date( 'Y-m-d H:i:s', $now - 200 ),296 ) );297 298 friends_add_friend( $u1, $u2, true );299 friends_add_friend( $u1, $u3, false );300 301 friends_check_friendship_status( $u1, $u2 );302 $first_query_count = $wpdb->num_queries;303 304 friends_check_friendship_status( $u1, $u3 );305 306 $this->assertEquals( $first_query_count, $wpdb->num_queries );307 }308 309 282 /** 310 283 * @group friendship_caching 311 284 */ … … class BP_Tests_Friends_Functions extends BP_UnitTestCase { 325 298 $first_query_count = $wpdb->num_queries; 326 299 327 300 /* 328 * We expect this to generate one query to find $u2's friendships, 329 * but the friendship object itself should come from cache. 301 * This should access the previous friendship check's cached items. 330 302 */ 331 303 friends_check_friendship_status( $u2, $u1 ); 332 304 333 $this->assertEquals( $first_query_count + 1, $wpdb->num_queries );305 $this->assertEquals( $first_query_count, $wpdb->num_queries ); 334 306 } 335 307 336 308 public function test_friends_get_recently_active() {