Make WordPress Core

Opened 2 months ago

Closed 8 weeks ago

#63004 closed enhancement (fixed)

Allow `count_many_users_posts()` to be short-circuited

Reported by: ethitter's profile ethitter Owned by: jorbin's profile jorbin
Milestone: 6.8 Priority: normal
Severity: normal Version:
Component: Users Keywords: has-patch commit
Focuses: administration, performance Cc:

Description

For a few reasons, it should be possible to prevent count_many_users_posts() from performing its query.

The first scenario comes into play when a plugin, such as Co-Authors Plus, removes the default count column. The WP_Users_List_Table class calls the function regardless of the columns presence, meaning the counts are never used.

Another scenario arises when a user has many, many posts. In one example, a user that is alphabetically first has 65,000 posts, which even on a performance-oriented host can take several seconds to count. Since the counts aren't cached, the delay can become burdensome when navigating through the users list.

Attachments (5)

63004.diff (413 bytes) - added by ethitter 2 months ago.
63004.2.diff (570 bytes) - added by ethitter 2 months ago.
Add documentation
63004.3.patch (1.3 KB) - added by jigar bhanushali 2 months ago.
GH-8410.diff (1.3 KB) - added by jigar bhanushali 2 months ago.
63004.5.patch (1.7 KB) - added by jigar bhanushali 2 months ago.

Download all attachments as: .zip

Change History (18)

@ethitter
2 months ago

#1 @audrasjb
2 months ago

Hello and thanks for the ticket/patch,

First, the new filter has to be documented using a regular docblock comment.

But I'm also wondering if we should rather use a more generic function to determine whether the user has a lot of posts, quite similarly to wp_is_large_network() does.

#2 @ethitter
2 months ago

I'll add the documentation on Monday; I'm kicking myself for omitting it.

I can see adding a default callback to the filter, but given the first scenario I described, I still believe a filter is useful for situations where the counts are never used.

@ethitter
2 months ago

Add documentation

#3 @jigar bhanushali
2 months ago

Hello @ethitter

I've uploaded the updated patch with additional improvements to the function.

I've updated the following line to better sanitize user IDs:

From:

$userlist = implode( ',', array_map( 'absint', $users ) );

To:

$userlist = implode( ',', wp_parse_id_list( $users ) );

I also added:

$count = array_fill_keys( $userlist, 0 );

This change eliminates the need for an extra foreach loop.

cc @audrasjb

Last edited 2 months ago by jigar bhanushali (previous) (diff)

#5 @audrasjb
2 months ago

Thank you both for your patches. I added a PR based on them to add a missing docblock info and to publicly run GitHub Actions against this changeset.

#6 @audrasjb
2 months ago

  • Keywords needs-refresh added

Please note that there is one PHP Unit Test issue to fix:

1) Tests_User::test_count_many_users_posts
array_fill_keys() expects parameter 1 to be array, string given

/var/www/src/wp-includes/user.php:683
/var/www/tests/phpunit/tests/user.php:589
phpvfscomposer:///var/www/vendor/phpunit/phpunit/phpunit:97
/var/www/vendor/bin/phpunit:118

This looks like a relevant regression.

#7 @jigar bhanushali
2 months ago

  • Keywords needs-refresh removed

@audrasjb Here is my updated patch and it seems not to create any regression issues.

#8 @jigar bhanushali
2 months ago

I have uploaded my latest patch as suggested by @peterwilsoncc

#9 @jorbin
8 weeks ago

  • Milestone changed from Awaiting Review to 6.8
  • Owner set to jorbin
  • Status changed from new to assigned

There isn't much time before beta 1, but I think this is a nice small enhancement that is worth including in 6.8.

@peterwilsoncc commented on PR #8410:


8 weeks ago
#10

@audrasjb I took the liberty of pushing @jigar787's patch (with a minor change) to your branch rather than create another PR for same.

#11 @peterwilsoncc
8 weeks ago

  • Keywords commit added

The tests are passing in the associated pull request based on 63004.5.patch.

I made a minor change and continued to use absint within the function to sanitize the user IDs to make sure that future changes to wp_parse_ids_list() don't have an inadvertent effect on escaping.

The unit test for return values and types are passing, as is manual testing.

@audrasjb commented on PR #8410:


8 weeks ago
#12

Great Peter 👍

#13 @peterwilsoncc
8 weeks ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 59900:

Users: Add pre-flight filter to count_many_users_posts().

Introduces the filter pre_count_many_users_posts() to allow developers to bypass the function in favour of either avoiding counts or their own counting functionality.

Props audrasjb, ethitter, jigar-bhanushali, jorbin.
Fixes #63004.

Note: See TracTickets for help on using tickets.