Ticket #6978: 6978.caching.01.patch
File 6978.caching.01.patch, 16.4 KB (added by , 8 years ago) |
---|
-
src/bp-friends/bp-friends-cache.php
diff --git src/bp-friends/bp-friends-cache.php src/bp-friends/bp-friends-cache.php index 5fb11a5..b4ac52e 100644
function friends_clear_friend_object_cache( $friendship_id ) { 26 26 if ( !$friendship = new BP_Friends_Friendship( $friendship_id ) ) 27 27 return false; 28 28 29 // @TODO: This is a cached set of random friends. Which is a weird thing to cache. Remove? 29 30 wp_cache_delete( 'friends_friend_ids_' . $friendship->initiator_user_id, 'bp' ); 30 31 wp_cache_delete( 'friends_friend_ids_' . $friendship->friend_user_id, 'bp' ); 31 32 } … … add_action( 'friends_friendship_accepted', 'friends_clear_friend_object_cache' ) 35 36 add_action( 'friends_friendship_deleted', 'friends_clear_friend_object_cache' ); 36 37 37 38 /** 39 * Clear friendship caches on friendship changes. 40 * 41 * @since 2.6.0 42 * 43 * @param int $friendship_id ID of the friendship that has changed. 44 * @param int $initiator_user_id ID of the first user. 45 * @param int $friend_user_id ID of the second user. 46 * @return bool 47 */ 48 function bp_friends_clear_bp_friends_friendships_cache( $friendship_id, $initiator_user_id, $friend_user_id ) { 49 wp_cache_delete( $initiator_user_id, 'bp_friends_friendships' ); 50 wp_cache_delete( $friend_user_id, 'bp_friends_friendships' ); 51 } 52 add_action( 'friends_friendship_requested', 'bp_friends_clear_bp_friends_friendships_cache', 10, 3 ); 53 add_action( 'friends_friendship_accepted', 'bp_friends_clear_bp_friends_friendships_cache', 10, 3 ); 54 add_action( 'friends_friendship_deleted', 'bp_friends_clear_bp_friends_friendships_cache', 10, 3 ); 55 56 /** 57 * Clear friendship caches on friendship changes. 58 * 59 * @since 2.6.0 60 * 61 * @param int $friendship_id The friendship ID. 62 * @param BP_Friends_Friendship $friendship Friendship object. 63 */ 64 function bp_friends_clear_bp_friends_friendships_cache_remove( $friendship_id, BP_Friends_Friendship $friendship ) { 65 wp_cache_delete( $friendship->initiator_user_id, 'bp_friends_friendships' ); 66 wp_cache_delete( $friendship->friend_user_id, 'bp_friends_friendships' ); 67 } 68 add_action( 'friends_friendship_withdrawn', 'bp_friends_clear_bp_friends_friendships_cache_remove', 10, 2 ); 69 add_action( 'friends_friendship_rejected', 'bp_friends_clear_bp_friends_friendships_cache_remove', 10, 2 ); 70 71 /** 38 72 * Clear the friend request cache for the user not initiating the friendship. 39 73 * 40 74 * @since 2.0.0 -
src/bp-friends/bp-friends-filters.php
diff --git src/bp-friends/bp-friends-filters.php src/bp-friends/bp-friends-filters.php index 3a06422..9513b47 100644
function bp_friends_filter_user_query_populate_extras( BP_User_Query $user_query 28 28 global $wpdb; 29 29 30 30 // Stop if user isn't logged in. 31 if ( ! is_user_logged_in() ) {31 if ( ! $user_id = bp_loggedin_user_id() ) { 32 32 return; 33 33 } 34 34 35 $ bp = buddypress();35 $maybe_friend_ids = wp_parse_id_list( $user_ids_sql ); 36 36 37 // Fetch whether or not the user is a friend of the current user. 38 $friend_status = $wpdb->get_results( $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 ( {$user_ids_sql} ) ) OR (initiator_user_id IN ( {$user_ids_sql} ) AND friend_user_id = %d )", bp_loggedin_user_id(), bp_loggedin_user_id() ) ); 39 40 // Keep track of members that have a friendship status with the current user. 41 $friend_user_ids = array(); 42 43 // The "friend" is the user ID in the pair who is *not* the logged in user. 44 foreach ( (array) $friend_status as $fs ) { 45 $friend_id = bp_loggedin_user_id() == $fs->initiator_user_id ? $fs->friend_user_id : $fs->initiator_user_id; 46 $friend_user_ids[] = $friend_id; 47 48 if ( isset( $user_query->results[ $friend_id ] ) ) { 49 if ( 0 == $fs->is_confirmed ) { 50 $status = $fs->initiator_user_id == bp_loggedin_user_id() ? 'pending' : 'awaiting_response'; 51 } else { 52 $status = 'is_friend'; 53 } 54 55 $user_query->results[ $friend_id ]->is_friend = $fs->is_confirmed; 56 $user_query->results[ $friend_id ]->friendship_status = $status; 57 } 58 } 59 60 // The rest are not friends with the current user, so set status accordingly. 61 $not_friends = array_diff( $user_query->user_ids, $friend_user_ids ); 62 foreach ( (array) $not_friends as $nf ) { 63 if ( bp_loggedin_user_id() == $nf ) { 64 continue; 65 } 66 67 if ( isset( $user_query->results[ $nf ] ) ) { 68 $user_query->results[ $nf ]->friendship_status = 'not_friends'; 37 foreach ( $maybe_friend_ids as $friend_id ) { 38 $status = BP_Friends_Friendship::check_is_friend( $user_id, $friend_id ); 39 $user_query->results[ $friend_id ]->friendship_status = $status; 40 if ( 'is_friend' == $status ) { 41 $user_query->results[ $friend_id ]->is_friend = 1; 69 42 } 70 43 } 71 44 -
src/bp-friends/classes/class-bp-friends-component.php
diff --git src/bp-friends/classes/class-bp-friends-component.php src/bp-friends/classes/class-bp-friends-component.php index ce0308a..b27f76f 100644
class BP_Friends_Component extends BP_Component { 284 284 285 285 // Global groups. 286 286 wp_cache_add_global_groups( array( 287 'bp_friends_requests' 287 'bp_friends_requests', // This can go? 288 'bp_friends_friendships' 288 289 ) ); 289 290 290 291 parent::setup_cache_groups(); -
src/bp-friends/classes/class-bp-friends-friendship.php
diff --git src/bp-friends/classes/class-bp-friends-friendship.php src/bp-friends/classes/class-bp-friends-friendship.php index 5543502d..525f04b 100644
class BP_Friends_Friendship { 206 206 /** Static Methods ********************************************************/ 207 207 208 208 /** 209 * Get the friendships for a given user. 210 * 211 * @since 2.6.0 212 * 213 * @param int $user_id ID of the user whose friends are being retrieved. 214 * @param array $args { 215 * Optional. Filter parameters. 216 * @type int $id ID of specific friendship to retrieve. 217 * @type int $initiator_user_id ID of friendship initiator. 218 * @type int $friend_user_id ID of specific friendship to retrieve. 219 * @type int $is_confirmed Whether the friendship has been accepted. 220 * @type int $is_limited Whether the friendship is limited. 221 * @type string $order_by Column name to order by. 222 * @type string $sort_order ASC or DESC. Default DESC. 223 * } 224 * @param string $operator Optional. Operator to use in `wp_list_filter()`. 225 * 226 * @return array $friendships Array of friendship objects. 227 */ 228 public static function get_friendships( $user_id, $args = array(), $operator = 'AND' ) { 229 230 if ( empty( $user_id ) ) { 231 $user_id = bp_loggedin_user_id(); 232 } 233 234 $r = bp_parse_args( $args, array( 235 'id' => 0, 236 'initiator_user_id' => 0, 237 'friend_user_id' => 0, 238 'is_confirmed' => false, 239 'is_limited' => false, 240 'order_by' => 'date_created', 241 'sort_order' => 'DESC', 242 'page' => false, 243 'per_page' => false 244 ), 'bp_get_user_friendships' ); 245 246 // First, we get all friendships that involve the user. 247 $friendships = wp_cache_get( $user_id, 'bp_friends_friendships' ); 248 if ( false === $friendships ) { 249 global $wpdb; 250 $bp = buddypress(); 251 252 $friendships = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->friends->table_name} WHERE (initiator_user_id = %d OR friend_user_id = %d) ORDER BY date_created DESC", $user_id, $user_id ) ); 253 wp_cache_set( $user_id, $friendships, 'bp_friends_friendships' ); 254 } 255 256 if ( ! $friendships ) { 257 return array(); 258 } 259 260 // Normalize friendship data. 261 foreach ( $friendships as &$friendship ) { 262 // Integer values. 263 foreach ( array( 'id', 'initiator_user_id', 'friend_user_id' ) as $index ) { 264 $friendship->{$index} = intval( $friendship->{$index} ); 265 } 266 // Boolean values. 267 $friendship->is_confirmed = (bool) $friendship->is_confirmed; 268 $friendship->is_limited = (bool) $friendship->is_limited; 269 } 270 271 // Assemble filter array for use in `wp_list_filter()`. 272 $filters = wp_array_slice_assoc( $r, array( 'id', 'initiator_user_id', 'friend_user_id', 'is_confirmed', 'is_limited' ) ); 273 foreach ( $filters as $filter_name => $filter_value ) { 274 if ( in_array( $filter_name, array( 'is_confirmed', 'is_limited' ) ) ) { 275 // Separate 'false' from meaningful 0s. 276 if ( false === $filter_value ) { 277 unset( $filters[ $filter_name ] ); 278 } 279 } elseif ( ! $filter_value ) { 280 unset( $filters[ $filter_name ] ); 281 } 282 } 283 284 if ( ! empty( $filters ) ) { 285 $friendships = wp_list_filter( $friendships, $filters, $operator ); 286 } 287 288 // Sort the results on a column name. 289 if ( in_array( $r['order_by'], array( 'id', 'initiator_user_id', 'friend_user_id' ) ) ) { 290 $friendships = bp_sort_by_key( $friendships, $r['order_by'] ); 291 } 292 293 // Adjust the sort direction of the results. 294 if ( 'ASC' === strtoupper( $r['sort_order'] ) ) { 295 // `true` to preserve keys. 296 $friendships = array_reverse( $friendships, true ); 297 } 298 299 // Paginate the results. 300 if ( $r['per_page'] && $r['page'] ) { 301 $start = ( $r['page'] - 1 ) * ( $r['per_page'] ); 302 $friendships = array_slice( $friendships, $start, $r['per_page'] ); 303 } 304 305 return $friendships; 306 } 307 308 /** 209 309 * Get the IDs of a given user's friends. 210 310 * 211 311 * @since 1.0.0 … … class BP_Friends_Friendship { 221 321 public static function get_friend_user_ids( $user_id, $friend_requests_only = false, $assoc_arr = false ) { 222 322 global $wpdb; 223 323 224 if ( !empty( $friend_requests_only ) ) { 225 $oc_sql = 'AND is_confirmed = 0'; 226 $friend_sql = $wpdb->prepare( " WHERE friend_user_id = %d", $user_id ); 324 if ( ! empty( $friend_requests_only ) ) { 325 $args = array( 326 'is_confirmed' => 0, 327 'friend_user_id' => $user_id 328 ); 227 329 } else { 228 $oc_sql = 'AND is_confirmed = 1'; 229 $friend_sql = $wpdb->prepare( " WHERE (initiator_user_id = %d OR friend_user_id = %d)", $user_id, $user_id ); 330 $args = array( 331 'is_confirmed' => 1, 332 ); 230 333 } 231 334 232 $bp = buddypress(); 233 $friends = $wpdb->get_results( "SELECT friend_user_id, initiator_user_id FROM {$bp->friends->table_name} {$friend_sql} {$oc_sql} ORDER BY date_created DESC" ); 234 $fids = array(); 335 $friendships = self::get_friendships( $user_id, $args ); 235 336 236 for ( $i = 0, $count = count( $friends ); $i < $count; ++$i ) { 237 if ( !empty( $assoc_arr ) ) { 238 $fids[] = array( 'user_id' => ( $friends[$i]->friend_user_id == $user_id ) ? $friends[$i]->initiator_user_id : $friends[$i]->friend_user_id ); 337 $fids = array(); 338 foreach ( $friendships as $friendship ) { 339 if ( ! empty( $assoc_arr ) ) { 340 $fids[] = array( 'user_id' => ( $friendship->friend_user_id == $user_id ) ? $friendship->initiator_user_id : $friendship->friend_user_id ); 239 341 } else { 240 $fids[] = ( $friends [$i]->friend_user_id == $user_id ) ? $friends[$i]->initiator_user_id : $friends[$i]->friend_user_id;342 $fids[] = ( $friendship->friend_user_id == $user_id ) ? $friendship->initiator_user_id : $friendship->friend_user_id; 241 343 } 242 344 } 243 345 … … class BP_Friends_Friendship { 254 356 * @return int|bool The ID of the friendship object if found, otherwise false. 255 357 */ 256 358 public static function get_friendship_id( $user_id, $friend_id ) { 257 global $wpdb;359 $friendship_id = null; 258 360 259 $bp = buddypress(); 361 // Can't friend yourself. 362 if ( $user_id == $friend_id ) { 363 return $friendship_id; 364 } 260 365 261 return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->friends->table_name} WHERE ( initiator_user_id = %d AND friend_user_id = %d ) OR ( initiator_user_id = %d AND friend_user_id = %d ) AND is_confirmed = 1", $user_id, $friend_id, $friend_id, $user_id ) ); 366 /* 367 * Find friendships where the possible_friend_userid is the 368 * initiator or friend. 369 */ 370 $args = array( 371 'initiator_user_id' => $friend_id, 372 'friend_user_id' => $friend_id 373 ); 374 $result = self::get_friendships( $user_id, $args, 'OR' ); 375 if ( $result ) { 376 $friendship_id = current( $result )->id; 377 } 378 379 return $friendship_id; 262 380 } 263 381 264 382 /** … … class BP_Friends_Friendship { 274 392 $friend_requests = wp_cache_get( $user_id, 'bp_friends_requests' ); 275 393 276 394 if ( false === $friend_requests ) { 277 global $wpdb; 278 279 $bp = buddypress(); 280 281 $friend_requests = $wpdb->get_col( $wpdb->prepare( "SELECT initiator_user_id FROM {$bp->friends->table_name} WHERE friend_user_id = %d AND is_confirmed = 0", $user_id ) ); 395 //@TODO: this uses already cached data, so maybe `bp_friends_requests` should go away? 396 $friend_requests = self::get_friend_user_ids( $user_id, true ); 282 397 283 398 wp_cache_set( $user_id, $friend_requests, 'bp_friends_requests' ); 284 399 } … … class BP_Friends_Friendship { 299 414 public static function total_friend_count( $user_id = 0 ) { 300 415 global $wpdb; 301 416 302 if ( empty( $user_id ) ) 417 if ( empty( $user_id ) ) { 303 418 $user_id = ( bp_displayed_user_id() ) ? bp_displayed_user_id() : bp_loggedin_user_id(); 304 305 $bp = buddypress(); 419 } 306 420 307 421 /* 308 422 * This is stored in 'total_friend_count' usermeta. 309 423 * This function will recalculate, update and return. 310 424 */ 311 425 312 $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->friends->table_name} WHERE (initiator_user_id = %d OR friend_user_id = %d) AND is_confirmed = 1", $user_id, $user_id ) ); 426 $args = array( 427 'is_confirmed' => 1, 428 ); 429 $friendships = self::get_friendships( $user_id, $args ); 430 $count = count( $friendships ); 313 431 314 432 // Do not update meta if user has never had friends. 315 if ( empty( $count ) && !bp_get_user_meta( $user_id, 'total_friend_count', true ) )433 if ( ! $count && ! bp_get_user_meta( $user_id, 'total_friend_count', true ) ) { 316 434 return 0; 435 } 317 436 318 437 bp_update_user_meta( $user_id, 'total_friend_count', (int) $count ); 319 438 … … class BP_Friends_Friendship { 408 527 return false; 409 528 } 410 529 411 $bp = buddypress(); 412 413 $result = $wpdb->get_results( $wpdb->prepare( "SELECT id, initiator_user_id, is_confirmed FROM {$bp->friends->table_name} WHERE (initiator_user_id = %d AND friend_user_id = %d) OR (initiator_user_id = %d AND friend_user_id = %d)", $initiator_userid, $possible_friend_userid, $possible_friend_userid, $initiator_userid ) ); 530 // Can't friend yourself. 531 if ( $initiator_userid == $possible_friend_userid ) { 532 return 'not_friends'; 533 } 414 534 415 if ( ! empty( $result ) ) { 416 if ( 0 == (int) $result[0]->is_confirmed ) { 417 $status = $initiator_userid == $result[0]->initiator_user_id ? 'pending' : 'awaiting_response'; 535 /* 536 * Find friendships where the possible_friend_userid is the 537 * initiator or friend. 538 */ 539 $args = array( 540 'initiator_user_id' => $possible_friend_userid, 541 'friend_user_id' => $possible_friend_userid 542 ); 543 $result = self::get_friendships( $initiator_userid, $args, 'OR' ); 544 545 if ( $result ) { 546 $friendship = current( $result ); 547 if ( ! $friendship->is_confirmed ) { 548 $status = $initiator_userid == $friendship->initiator_user_id ? 'pending' : 'awaiting_response'; 418 549 } else { 419 550 $status = 'is_friend'; 420 551 } … … class BP_Friends_Friendship { 470 601 * @param int $friendship_id ID of the friendship to be accepted. 471 602 * @return int Number of database rows updated. 472 603 */ 473 public static function accept( $friendship_id) {604 public static function accept( $friendship_id ) { 474 605 global $wpdb; 475 606 476 607 $bp = buddypress(); … … class BP_Friends_Friendship { 486 617 * @param int $friendship_id ID of the friendship to be withdrawn. 487 618 * @return int Number of database rows deleted. 488 619 */ 489 public static function withdraw( $friendship_id) {620 public static function withdraw( $friendship_id ) { 490 621 global $wpdb; 491 622 492 623 $bp = buddypress(); … … class BP_Friends_Friendship { 502 633 * @param int $friendship_id ID of the friendship to be rejected. 503 634 * @return int Number of database rows deleted. 504 635 */ 505 public static function reject( $friendship_id) {636 public static function reject( $friendship_id ) { 506 637 global $wpdb; 507 638 508 639 $bp = buddypress(); … … class BP_Friends_Friendship { 730 861 // Loop through friend_ids and update their counts. 731 862 foreach ( (array) $friend_ids as $friend_id ) { 732 863 BP_Friends_Friendship::total_friend_count( $friend_id ); 864 // Delete cached friendships. 865 wp_cache_delete( $friend_id, 'bp_friends_friendships' ); 733 866 } 867 868 // Delete cached friendships. 869 wp_cache_delete( $user_id, 'bp_friends_friendships' ); 870 734 871 } 735 872 }