Ticket #8688: 8688.2.patch
File 8688.2.patch, 11.6 KB (added by , 3 years ago) |
---|
-
src/bp-groups/bp-groups-admin.php
diff --git src/bp-groups/bp-groups-admin.php src/bp-groups/bp-groups-admin.php index a9701c106..e9674d433 100644
function bp_groups_admin_load() { 354 354 } 355 355 356 356 if ( ! empty( $user_names ) ) { 357 $new_members = count( $user_names ); 358 359 if ( 1 < $new_members ) { 360 bp_groups_defer_group_members_count( $group_id, true ); 361 } 357 362 358 363 foreach( array_values( $user_names ) as $user_name ) { 359 364 $un = trim( $user_name ); … … function bp_groups_admin_load() { 372 377 } 373 378 } 374 379 } 380 381 if ( 1 < $new_members ) { 382 bp_groups_defer_group_members_count( $group_id, false ); 383 } 375 384 } 376 385 377 386 // Process member role changes. -
src/bp-groups/bp-groups-functions.php
diff --git src/bp-groups/bp-groups-functions.php src/bp-groups/bp-groups-functions.php index 4e3183e09..b1c23fb51 100644
function bp_init_group_extensions() { 3678 3678 } 3679 3679 } 3680 3680 add_action( 'bp_init', 'bp_init_group_extensions', 11 ); 3681 3682 /** 3683 * Updates a group members count when a user joined or left the group. 3684 * 3685 * @since 10.3.0 3686 * 3687 * @param BP_Groups_Member|int $groups_member The BP_Groups_Member object or the group member ID. 3688 * @param int $group_id The group's ID. 3689 */ 3690 function bp_groups_update_group_members_count( $groups_member, $group_id = 0 ) { 3691 if ( true === $groups_member instanceof BP_Groups_Member ) { 3692 $group_id = $groups_member->group_id; 3693 } 3694 3695 BP_Groups_Member::refresh_total_member_count_for_group( (int) $group_id ); 3696 } 3697 add_action( 'groups_member_after_save', 'bp_groups_update_group_members_count' ); 3698 add_action( 'groups_member_after_remove', 'bp_groups_update_group_members_count' ); 3699 add_action( 'bp_groups_member_after_delete', 'bp_groups_update_group_members_count', 10, 2 ); 3700 3701 /** 3702 * Defers a group's counting to avoid updating it when batch adding/removing users to this group. 3703 * 3704 * @since 10.3.0 3705 * 3706 * @param int $group_id The group's ID. 3707 * @param bool $defer True to defer, false otherwise. 3708 */ 3709 function bp_groups_defer_group_members_count( $group_id = 0, $defer = true ) { 3710 if ( $defer ) { 3711 remove_action( 'groups_member_after_save', 'bp_groups_update_group_members_count' ); 3712 remove_action( 'groups_member_after_remove', 'bp_groups_update_group_members_count' ); 3713 remove_action( 'bp_groups_member_after_delete', 'bp_groups_update_group_members_count', 10, 2 ); 3714 } else { 3715 add_action( 'groups_member_after_save', 'bp_groups_update_group_members_count' ); 3716 add_action( 'groups_member_after_remove', 'bp_groups_update_group_members_count' ); 3717 add_action( 'bp_groups_member_after_delete', 'bp_groups_update_group_members_count', 10, 2 ); 3718 3719 BP_Groups_Member::refresh_total_member_count_for_group( (int) $group_id ); 3720 } 3721 } -
src/bp-groups/classes/class-bp-group-member-query.php
diff --git src/bp-groups/classes/class-bp-group-member-query.php src/bp-groups/classes/class-bp-group-member-query.php index 267c81e09..d91224978 100644
class BP_Group_Member_Query extends BP_User_Query { 49 49 */ 50 50 protected $group_member_ids; 51 51 52 /** 53 * Constructor. 54 * 55 * @since 10.3.0 56 * 57 * @param string|array|null $query See {@link BP_User_Query}. 58 */ 59 public function __construct( $query = null ) { 60 $qv = bp_parse_args( 61 $query, 62 array( 63 'count' => false, // True to perform a count query. False otherwise. 64 ) 65 ); 66 67 parent::__construct( $qv ); 68 } 69 52 70 /** 53 71 * Set up action hooks. 54 72 * … … class BP_Group_Member_Query extends BP_User_Query { 62 80 $this->query_vars_raw['type'] = 'last_joined'; 63 81 } 64 82 65 // Set the sort order. 66 add_action( 'bp_pre_user_query', array( $this, 'set_orderby' ) ); 83 if ( ! $this->query_vars_raw['count'] ) { 84 // Set the sort order. 85 add_action( 'bp_pre_user_query', array( $this, 'set_orderby' ) ); 67 86 68 // Set up our populate_extras method. 69 add_action( 'bp_user_query_populate_extras', array( $this, 'populate_group_member_extras' ), 10, 2 ); 87 // Set up our populate_extras method. 88 add_action( 'bp_user_query_populate_extras', array( $this, 'populate_group_member_extras' ), 10, 2 ); 89 } else { 90 $this->query_vars_raw['orderby'] = 'ID'; 91 } 92 } 93 94 /** 95 * Use WP_User_Query() to pull data for the user IDs retrieved in the main query. 96 * 97 * If a `count` query is performed, the function is used to validate existing users. 98 * 99 * @since 10.3.0 100 */ 101 public function do_wp_user_query() { 102 if ( ! $this->query_vars_raw['count'] ) { 103 return parent::do_wp_user_query(); 104 } 105 106 /** 107 * Filters the WP User Query arguments before passing into the class. 108 * 109 * @since 10.3.0 110 * 111 * @param array $value Array of arguments for the user query. 112 * @param BP_User_Query $this Current BP_User_Query instance. 113 */ 114 $wp_user_query = new WP_User_Query( 115 apply_filters( 116 'bp_group_members_count_query_args', 117 array( 118 // Relevant. 119 'fields' => 'ID', 120 'include' => $this->user_ids, 121 122 // Overrides 123 'blog_id' => 0, // BP does not require blog roles. 124 'count_total' => false // We already have a count. 125 126 ), 127 $this 128 ) 129 ); 130 131 // Validate existing user IDs. 132 $this->user_ids = array_map( 'intval', $wp_user_query->results ); 133 $this->results = $this->user_ids; 134 135 // Set the total existing users. 136 $this->total_users = count( $this->user_ids ); 70 137 } 71 138 72 139 /** … … class BP_Group_Member_Query extends BP_User_Query { 473 540 474 541 return wp_list_pluck( $group_user_ids, 'user_id' ); 475 542 } 543 544 /** 545 * Perform a database query to populate any extra metadata we might need. 546 * 547 * If a `count` query is performed, the function is used to validate active users. 548 * 549 * @since 10.3.0 550 */ 551 public function populate_extras() { 552 if ( ! $this->query_vars_raw['count'] ) { 553 return parent::populate_extras(); 554 } 555 556 // Validate active users. 557 $active_users = array_filter( BP_Core_User::get_last_activity( $this->user_ids ) ); 558 $active_user_ids = array_keys( $active_users ); 559 $this->results = array_intersect( $this->user_ids, $active_user_ids ); 560 561 // Set the total active users. 562 $this->total_users = count( $this->results ); 563 } 476 564 } -
src/bp-groups/classes/class-bp-groups-group.php
diff --git src/bp-groups/classes/class-bp-groups-group.php src/bp-groups/classes/class-bp-groups-group.php index c0b518237..e837d72ed 100644
class BP_Groups_Group { 1789 1789 * @return int Count of confirmed members for the group. 1790 1790 */ 1791 1791 public static function get_total_member_count( $group_id, $skip_cache = false ) { 1792 $ cache_key = 'total_member_count';1793 $count = groups_get_groupmeta( $group_id, $cache_key );1792 $meta_key = 'total_member_count'; 1793 $count = groups_get_groupmeta( $group_id, $meta_key ); 1794 1794 1795 1795 if ( false === $count || true === $skip_cache ) { 1796 $ members = groups_get_group_members(1796 $group_members = new BP_Group_Member_Query( 1797 1797 array( 1798 1798 'group_id' => $group_id, 1799 1799 'group_role' => array( 'member', 'admin', 'mod' ), 1800 ' type' => 'active',1800 'count' => true, 1801 1801 ) 1802 1802 ); 1803 1803 1804 $count = $members['count'] ? $members['count'] : 0; 1805 1806 groups_update_groupmeta( $group_id, $cache_key, (int) $count ); 1804 $count = $group_members->total_users; 1805 groups_update_groupmeta( $group_id, $meta_key, $count ); 1807 1806 } 1808 1807 1809 1808 /** … … class BP_Groups_Group { 1814 1813 * @param int $count Total member count for group. 1815 1814 * @param int $group_id The ID of the group. 1816 1815 */ 1817 return (int) apply_filters( 'bp_groups_total_member_count', (int)$count, (int) $group_id );1816 return (int) apply_filters( 'bp_groups_total_member_count', $count, (int) $group_id ); 1818 1817 } 1819 1818 1820 1819 /** -
src/bp-groups/classes/class-bp-groups-member.php
diff --git src/bp-groups/classes/class-bp-groups-member.php src/bp-groups/classes/class-bp-groups-member.php index d938800fe..10d511d45 100644
class BP_Groups_Member { 309 309 // Update the user's group count. 310 310 self::refresh_total_group_count_for_user( $this->user_id ); 311 311 312 // Update the group's member count.313 self::refresh_total_member_count_for_group( $this->group_id );314 315 312 /** 316 313 * Fires after the current group membership item has been saved. 317 314 * … … class BP_Groups_Member { 447 444 // Update the user's group count. 448 445 self::refresh_total_group_count_for_user( $this->user_id ); 449 446 450 // Update the group's member count.451 self::refresh_total_member_count_for_group( $this->group_id );452 453 447 /** 454 448 * Fires after a member is removed from a group. 455 449 * … … class BP_Groups_Member { 517 511 // Update the user's group count. 518 512 self::refresh_total_group_count_for_user( $user_id ); 519 513 520 // Update the group's member count.521 self::refresh_total_member_count_for_group( $group_id );522 523 514 /** 524 515 * Fires after a member is removed from a group. 525 516 * -
tests/phpunit/testcases/groups/functions.php
diff --git tests/phpunit/testcases/groups/functions.php tests/phpunit/testcases/groups/functions.php index 208378547..a6d9059cc 100644
7 7 class BP_Tests_Groups_Functions extends BP_UnitTestCase { 8 8 static public $group_ids; 9 9 static public $user_ids; 10 protected $did_group_member_count = 0; 10 11 11 12 static public function wpSetUpBeforeClass( $factory ) { 12 13 self::$user_ids = $factory->user->create_many( 3 ); … … class BP_Tests_Groups_Functions extends BP_UnitTestCase { 344 345 $this->assertEquals( 2, BP_Groups_Group::get_total_member_count( $g1 ) ); 345 346 } 346 347 348 /** 349 * @group total_member_count 350 * @ticket BP8688 351 */ 352 public function test_total_member_count_groups_inactive_user() { 353 $u1 = self::factory()->user->create(); 354 $u2 = wp_insert_user( array( 355 'user_pass' => 'foobar', 356 'user_login' => 'foobar', 357 'user_email' => 'foobar@buddypress.org', 358 ) ); 359 360 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) ); 361 362 groups_join_group( $g1, $u2 ); 363 364 $this->assertEquals( 1, groups_get_total_member_count( $g1 ) ); 365 } 366 367 /** 368 * @group total_member_count 369 * @ticket BP8688 370 */ 371 public function test_total_member_count_groups_spammed_user() { 372 $u1 = self::factory()->user->create(); 373 $u2 = self::factory()->user->create(); 374 375 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) ); 376 377 groups_join_group( $g1, $u2 ); 378 bp_core_process_spammer_status( $u2, 'spam' ); 379 380 $this->assertEquals( 1, groups_get_total_member_count( $g1 ) ); 381 } 382 383 /** 384 * @group total_member_count 385 * @ticket BP8688 386 */ 387 public function test_total_member_count_groups_deferred() { 388 $u1 = self::factory()->user->create(); 389 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) ); 390 $members = array(); 391 $this->did_group_member_count = 0; 392 393 add_filter( 'bp_groups_total_member_count', array( $this, 'filter_bp_groups_total_member_count' ) ); 394 395 bp_groups_defer_group_members_count( $g1, true ); 396 for ( $i = 1; $i < 6; $i++ ) { 397 $members[ $i ] = self::factory()->user->create(); 398 groups_join_group( $g1, $members[ $i ] ); 399 } 400 bp_groups_defer_group_members_count( $g1, false ); 401 402 remove_filter( 'bp_groups_total_member_count', array( $this, 'filter_bp_groups_total_member_count' ) ); 403 404 $this->assertTrue( 1 === $this->did_group_member_count ); 405 $this->assertEquals( count( $members ) + 1, groups_get_total_member_count( $g1 ) ); 406 } 407 408 public function filter_bp_groups_total_member_count( $count ) { 409 $this->did_group_member_count += 1; 410 return $count; 411 } 412 347 413 /** 348 414 * @group total_member_count 349 415 * @group groups_create_group