Make WordPress Core


Ignore:
Timestamp:
03/29/2022 12:41:00 PM (18 months ago)
Author:
spacedmonkey
Message:

Users: Introduce the concept of a large site to single site installations.

Currently in WordPress multisite there is a concept of large networks. The function wp_is_large_network is used to determine if a network has a large number of sites or users. If a network is marked as large, then
expensive queries to calculate user counts are not run on page load but deferred to scheduled events. However there are a number of places in a single site installation where this functionality would also be useful, as
expensive calls to count users and roles can make screens in the admin extremely slow.

In this change, the get_user_count function and related functionality around it is ported to be available in a single site context. This means that expensive calls to the count_users function are replaced with
calls to get_user_count. This change also includes a new function called wp_is_large_user_count and a filter of the same name, to mark if a site is large.

Props johnbillion, Spacedmonkey, Mista-Flo, lumpysimon, tharsheblows, obenland, miss_jwo, jrchamp, flixos90, macbookandrew, pento, desrosj, johnjamesjacoby, jb510, davidbaumwald, costdev.
Fixes #38741.

File:
1 edited

Legend:

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

    r52955 r53011  
    84198419    return abs( (float) $expected - (float) $actual ) <= $precision;
    84208420}
     8421
     8422/**
     8423 * Returns the number of active users in your installation.
     8424 *
     8425 * Note that on a large site the count may be cached and only updated twice daily.
     8426 *
     8427 * @since MU (3.0.0)
     8428 * @since 4.8.0 The `$network_id` parameter has been added.
     8429 * @since 6.0.0 Move to wp-includes/functions.php.
     8430 *
     8431 * @param int|null $network_id ID of the network. Default is the current network.
     8432 * @return int Number of active users on the network.
     8433 */
     8434function get_user_count( $network_id = null ) {
     8435    if ( ! is_multisite() && null !== $network_id ) {
     8436        _doing_it_wrong( __FUNCTION__, __( 'Unable to pass $network_id if not using multisite.' ), '6.0.0' );
     8437    }
     8438    return (int) get_network_option( $network_id, 'user_count', -1 );
     8439}
     8440
     8441/**
     8442 * Updates the total count of users on the site if live user counting is enabled.
     8443 *
     8444 * @since 6.0.0
     8445 *
     8446 * @param int|null $network_id ID of the network. Default is the current network.
     8447 * @return bool Whether the update was successful.
     8448 */
     8449function wp_maybe_update_user_counts( $network_id = null ) {
     8450    if ( ! is_multisite() && null !== $network_id ) {
     8451        _doing_it_wrong( __FUNCTION__, __( 'Unable to pass $network_id if not using multisite.' ), '6.0.0' );
     8452    }
     8453
     8454    $is_small_network = ! wp_is_large_user_count( $network_id );
     8455    /** This filter is documented in wp-includes/ms-functions.php */
     8456    if ( ! apply_filters( 'enable_live_network_counts', $is_small_network, 'users' ) ) {
     8457        return false;
     8458    }
     8459
     8460    return wp_update_user_counts( $network_id );
     8461}
     8462
     8463/**
     8464 * Updates the total count of users on the site.
     8465 *
     8466 * @global wpdb $wpdb WordPress database abstraction object.
     8467 * @since 6.0.0
     8468 *
     8469 * @param int|null $network_id ID of the network. Default is the current network.
     8470 * @return bool Whether the update was successful.
     8471 */
     8472function wp_update_user_counts( $network_id = null ) {
     8473    global $wpdb;
     8474
     8475    if ( ! is_multisite() && null !== $network_id ) {
     8476        _doing_it_wrong( __FUNCTION__, __( 'Unable to pass $network_id if not using multisite.' ), '6.0.0' );
     8477    }
     8478
     8479    $query = "SELECT COUNT(ID) as c FROM $wpdb->users";
     8480    if ( is_multisite() ) {
     8481        $query .= " WHERE spam = '0' AND deleted = '0'";
     8482    }
     8483
     8484    $count = $wpdb->get_var( $query );
     8485
     8486    return update_network_option( $network_id, 'user_count', $count );
     8487}
     8488
     8489/**
     8490 * Schedules a recurring recalculation of the total count of users.
     8491 *
     8492 * @since 6.0.0
     8493 */
     8494function wp_schedule_update_user_counts() {
     8495    if ( ! is_main_site() ) {
     8496        return;
     8497    }
     8498
     8499    if ( ! wp_next_scheduled( 'wp_update_user_counts' ) && ! wp_installing() ) {
     8500        wp_schedule_event( time(), 'twicedaily', 'wp_update_user_counts' );
     8501    }
     8502}
     8503
     8504/**
     8505 * Determines whether the site has a large number of users.
     8506 *
     8507 * The default criteria for a large site is more than 10,000 users.
     8508 *
     8509 * @since 6.0.0
     8510 *
     8511 * @param int|null $network_id ID of the network. Default is the current network.
     8512 * @return bool Whether the site has a large number of users.
     8513 */
     8514function wp_is_large_user_count( $network_id = null ) {
     8515    if ( ! is_multisite() && null !== $network_id ) {
     8516        _doing_it_wrong( __FUNCTION__, __( 'Unable to pass $network_id if not using multisite.' ), '6.0.0' );
     8517    }
     8518    $count = get_user_count( $network_id );
     8519
     8520    /**
     8521     * Filters whether the site is considered large, based on its number of users.
     8522     *
     8523     * @since 6.0.0
     8524     *
     8525     * @param bool     $is_large_user_count Whether the site has a large number of users.
     8526     * @param int      $count               The total number of users.
     8527     * @param int|null $network_id          ID of the network. `null` represents the current network.
     8528     */
     8529    return apply_filters( 'wp_is_large_user_count', $count > 10000, $count, $network_id );
     8530}
Note: See TracChangeset for help on using the changeset viewer.