Make WordPress Core


Ignore:
Timestamp:
10/15/2025 11:56:57 PM (4 months ago)
Author:
peterwilsoncc
Message:

Users: Add caching to count_many_users_posts().

Introduces object caching to the count_many_users_posts() function.

Argument equivalency is checked prior to generating the cache key to ensure that the same cache is hit regardless of array order for users and post types. For example count_many_users_posts( [ 1, 2 ] ) will hit the same cache as count_many_users_posts( [ 2, 1 ] ).

Props adamsilverstein, flixos90, kalpeshh, rollybueno, sachinrajcp123, shailu25, sirlouen, spacedmonkey, westonruter, wildworks.
Fixes #63045.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/user.php

    r60712 r60941  
    650650 *
    651651 * @since 3.0.0
     652 * @since 6.9.0 The results are now cached.
    652653 *
    653654 * @global wpdb $wpdb WordPress database abstraction object.
     
    656657 * @param string|string[] $post_type   Optional. Single post type or array of post types to check. Defaults to 'post'.
    657658 * @param bool            $public_only Optional. Only return counts for public posts.  Defaults to false.
    658  * @return string[] Amount of posts each user has written, as strings, keyed by user ID.
     659 * @return array<int, string> Amount of posts each user has written, as strings, keyed by user ID.
    659660 */
    660661function count_many_users_posts( $users, $post_type = 'post', $public_only = false ) {
     
    683684    }
    684685
    685     $userlist = implode( ',', array_map( 'absint', $users ) );
    686     $where    = get_posts_by_author_sql( $post_type, true, null, $public_only );
    687 
    688     $result = $wpdb->get_results( "SELECT post_author, COUNT(*) FROM $wpdb->posts $where AND post_author IN ($userlist) GROUP BY post_author", ARRAY_N );
    689 
    690     $count = array_fill_keys( $users, 0 );
    691     foreach ( $result as $row ) {
    692         $count[ $row[0] ] = $row[1];
     686    // Cleanup the users array. Remove duplicates and sort for consistent ordering.
     687    $users = array_unique( array_filter( array_map( 'intval', $users ) ) );
     688    sort( $users );
     689
     690    // Cleanup the post type argument. Remove duplicates and sort for consistent ordering.
     691    $post_type = array_unique( (array) $post_type );
     692    sort( $post_type );
     693
     694    $userlist    = implode( ',', $users );
     695    $where       = get_posts_by_author_sql( $post_type, true, null, $public_only );
     696    $query       = "SELECT post_author, COUNT(*) FROM $wpdb->posts $where AND post_author IN ($userlist) GROUP BY post_author";
     697    $cache_key   = 'count_many_users_posts:' . md5( $query );
     698    $cache_salts = array( wp_cache_get_last_changed( 'posts' ), wp_cache_get_last_changed( 'users' ) );
     699    $count       = wp_cache_get_salted( $cache_key, 'post-queries', $cache_salts );
     700
     701    if ( false === $count ) {
     702        $where  = get_posts_by_author_sql( $post_type, true, null, $public_only );
     703        $result = $wpdb->get_results( "SELECT post_author, COUNT(*) FROM $wpdb->posts $where AND post_author IN ($userlist) GROUP BY post_author", ARRAY_N );
     704
     705        $count = array_fill_keys( $users, 0 );
     706        foreach ( $result as $row ) {
     707            $count[ $row[0] ] = $row[1];
     708        }
     709
     710        wp_cache_set_salted( $cache_key, $count, 'post-queries', $cache_salts, HOUR_IN_SECONDS );
    693711    }
    694712
Note: See TracChangeset for help on using the changeset viewer.