diff --git a/wp-admin/includes/class-wp-debug-data.php b/wp-admin/includes/class-wp-debug-data.php
index db34024e4fe..3d4e664ed70 100644
--- a/wp-admin/includes/class-wp-debug-data.php
+++ b/wp-admin/includes/class-wp-debug-data.php
@@ -388,11 +388,6 @@ public static function debug_data() {
$site_count += get_blog_count( $network_id );
}
- $info['wp-core']['fields']['user_count'] = array(
- 'label' => __( 'User count' ),
- 'value' => get_user_count(),
- );
-
$info['wp-core']['fields']['site_count'] = array(
'label' => __( 'Site count' ),
'value' => $site_count,
@@ -402,15 +397,13 @@ public static function debug_data() {
'label' => __( 'Network count' ),
'value' => $network_query->found_networks,
);
- } else {
- $user_count = count_users();
-
- $info['wp-core']['fields']['user_count'] = array(
- 'label' => __( 'User count' ),
- 'value' => $user_count['total_users'],
- );
}
+ $info['wp-core']['fields']['user_count'] = array(
+ 'label' => __( 'User count' ),
+ 'value' => get_user_count(),
+ );
+
// WordPress features requiring processing.
$wp_dotorg = wp_remote_get( 'https://wordpress.org', array( 'timeout' => 10 ) );
diff --git a/wp-admin/includes/class-wp-posts-list-table.php b/wp-admin/includes/class-wp-posts-list-table.php
index 96b3adb06b7..7fd4bf89ace 100644
--- a/wp-admin/includes/class-wp-posts-list-table.php
+++ b/wp-admin/includes/class-wp-posts-list-table.php
@@ -1653,7 +1653,7 @@ public function inline_edit() {
post_type, 'author' ) ) {
+ if ( post_type_supports( $screen->post_type, 'author' ) && ! wp_is_large_user_count() ) {
$authors_dropdown = '';
if ( current_user_can( $post_type_object->cap->edit_others_posts ) ) {
diff --git a/wp-admin/includes/class-wp-users-list-table.php b/wp-admin/includes/class-wp-users-list-table.php
index c01945e2eaa..1955e09fbc7 100644
--- a/wp-admin/includes/class-wp-users-list-table.php
+++ b/wp-admin/includes/class-wp-users-list-table.php
@@ -177,28 +177,33 @@ protected function get_views() {
$wp_roles = wp_roles();
+ $count_users = ! wp_is_large_user_count();
+
if ( $this->is_site_users ) {
$url = 'site-users.php?id=' . $this->site_id;
- switch_to_blog( $this->site_id );
- $users_of_blog = count_users( 'time', $this->site_id );
- restore_current_blog();
} else {
- $url = 'users.php';
- $users_of_blog = count_users();
+ $url = 'users.php';
}
- $total_users = $users_of_blog['total_users'];
- $avail_roles =& $users_of_blog['avail_roles'];
- unset( $users_of_blog );
-
+ $role_links = array();
+ $avail_roles = array();
+ $all_text = __( 'All' );
$current_link_attributes = empty( $role ) ? ' class="current" aria-current="page"' : '';
- $role_links = array();
- $role_links['all'] = sprintf(
- '%s',
- $url,
- $current_link_attributes,
- sprintf(
+ if ( $count_users ) {
+ if ( $this->is_site_users ) {
+ switch_to_blog( $this->site_id );
+ $users_of_blog = count_users( 'time', $this->site_id );
+ restore_current_blog();
+ } else {
+ $users_of_blog = count_users();
+ }
+
+ $total_users = $users_of_blog['total_users'];
+ $avail_roles =& $users_of_blog['avail_roles'];
+ unset( $users_of_blog );
+
+ $all_text = sprintf(
/* translators: %s: Number of users. */
_nx(
'All (%s)',
@@ -207,11 +212,13 @@ protected function get_views() {
'users'
),
number_format_i18n( $total_users )
- )
- );
+ );
+ }
+
+ $role_links['all'] = sprintf( '%s', $url, $current_link_attributes, $all_text );
foreach ( $wp_roles->get_names() as $this_role => $name ) {
- if ( ! isset( $avail_roles[ $this_role ] ) ) {
+ if ( $count_users && ! isset( $avail_roles[ $this_role ] ) ) {
continue;
}
@@ -222,12 +229,14 @@ protected function get_views() {
}
$name = translate_user_role( $name );
- $name = sprintf(
- /* translators: 1: User role name, 2: Number of users. */
- __( '%1$s (%2$s)' ),
- $name,
- number_format_i18n( $avail_roles[ $this_role ] )
- );
+ if ( $count_users ) {
+ $name = sprintf(
+ /* translators: 1: User role name, 2: Number of users. */
+ __( '%1$s (%2$s)' ),
+ $name,
+ number_format_i18n( $avail_roles[ $this_role ] )
+ );
+ }
$role_links[ $this_role ] = "$name";
}
diff --git a/wp-admin/includes/schema.php b/wp-admin/includes/schema.php
index d7728e2dff0..89ca9d8b303 100644
--- a/wp-admin/includes/schema.php
+++ b/wp-admin/includes/schema.php
@@ -1267,6 +1267,7 @@ function populate_network_meta( $network_id, array $meta = array() ) {
'subdomain_install' => $subdomain_install,
'global_terms_enabled' => global_terms_enabled() ? '1' : '0',
'ms_files_rewriting' => is_multisite() ? get_site_option( 'ms_files_rewriting' ) : '0',
+ 'user_count' => get_site_option( 'user_count' ),
'initial_db_version' => get_option( 'initial_db_version' ),
'active_sitewide_plugins' => array(),
'WPLANG' => get_locale(),
diff --git a/wp-admin/includes/upgrade.php b/wp-admin/includes/upgrade.php
index 88900bc400a..5e484374347 100644
--- a/wp-admin/includes/upgrade.php
+++ b/wp-admin/includes/upgrade.php
@@ -845,6 +845,10 @@ function upgrade_all() {
upgrade_590();
}
+ if ( $wp_current_db_version < 53011 ) {
+ upgrade_600();
+ }
+
maybe_disable_link_manager();
maybe_disable_automattic_widgets();
@@ -2282,6 +2286,22 @@ function upgrade_590() {
}
}
+/**
+ * Executes changes made in WordPress 6.0.0.
+ *
+ * @ignore
+ * @since 6.0.0
+ *
+ * @global int $wp_current_db_version The old (current) database version.
+ */
+function upgrade_600() {
+ global $wp_current_db_version;
+
+ if ( $wp_current_db_version < 53011 ) {
+ wp_update_user_counts();
+ }
+}
+
/**
* Executes network-level upgrade routines.
*
diff --git a/wp-includes/default-filters.php b/wp-includes/default-filters.php
index 182f94eddf5..124b1c24407 100644
--- a/wp-includes/default-filters.php
+++ b/wp-includes/default-filters.php
@@ -98,6 +98,13 @@
// Meta.
add_filter( 'register_meta_args', '_wp_register_meta_args_allowed_list', 10, 2 );
+// Counts.
+add_action( 'admin_init', 'wp_schedule_update_user_counts' );
+add_action( 'wp_update_user_counts', 'wp_schedule_update_user_counts', 10, 0 );
+foreach ( array( 'user_register', 'deleted_user' ) as $action ) {
+ add_action( $action, 'wp_maybe_update_user_counts', 10, 0 );
+}
+
// Post meta.
add_action( 'added_post_meta', 'wp_cache_set_posts_last_changed' );
add_action( 'updated_post_meta', 'wp_cache_set_posts_last_changed' );
diff --git a/wp-includes/functions.php b/wp-includes/functions.php
index 0e0f626e569..da5c6d37527 100644
--- a/wp-includes/functions.php
+++ b/wp-includes/functions.php
@@ -8418,3 +8418,113 @@ function is_php_version_compatible( $required ) {
function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) {
return abs( (float) $expected - (float) $actual ) <= $precision;
}
+
+/**
+ * Returns the number of active users in your installation.
+ *
+ * Note that on a large site the count may be cached and only updated twice daily.
+ *
+ * @since MU (3.0.0)
+ * @since 4.8.0 The `$network_id` parameter has been added.
+ * @since 6.0.0 Move to wp-includes/functions.php.
+ *
+ * @param int|null $network_id ID of the network. Default is the current network.
+ * @return int Number of active users on the network.
+ */
+function get_user_count( $network_id = null ) {
+ if ( ! is_multisite() && null !== $network_id ) {
+ _doing_it_wrong( __FUNCTION__, __( 'Unable to pass $network_id if not using multisite.' ), '6.0.0' );
+ }
+ return (int) get_network_option( $network_id, 'user_count', -1 );
+}
+
+/**
+ * Updates the total count of users on the site if live user counting is enabled.
+ *
+ * @since 6.0.0
+ *
+ * @param int|null $network_id ID of the network. Default is the current network.
+ * @return bool Whether the update was successful.
+ */
+function wp_maybe_update_user_counts( $network_id = null ) {
+ if ( ! is_multisite() && null !== $network_id ) {
+ _doing_it_wrong( __FUNCTION__, __( 'Unable to pass $network_id if not using multisite.' ), '6.0.0' );
+ }
+
+ $is_small_network = ! wp_is_large_user_count( $network_id );
+ /** This filter is documented in wp-includes/ms-functions.php */
+ if ( ! apply_filters( 'enable_live_network_counts', $is_small_network, 'users' ) ) {
+ return false;
+ }
+
+ return wp_update_user_counts( $network_id );
+}
+
+/**
+ * Updates the total count of users on the site.
+ *
+ * @global wpdb $wpdb WordPress database abstraction object.
+ * @since 6.0.0
+ *
+ * @param int|null $network_id ID of the network. Default is the current network.
+ * @return bool Whether the update was successful.
+ */
+function wp_update_user_counts( $network_id = null ) {
+ global $wpdb;
+
+ if ( ! is_multisite() && null !== $network_id ) {
+ _doing_it_wrong( __FUNCTION__, __( 'Unable to pass $network_id if not using multisite.' ), '6.0.0' );
+ }
+
+ $query = "SELECT COUNT(ID) as c FROM $wpdb->users";
+ if ( is_multisite() ) {
+ $query .= " WHERE spam = '0' AND deleted = '0'";
+ }
+
+ $count = $wpdb->get_var( $query );
+
+ return update_network_option( $network_id, 'user_count', $count );
+}
+
+/**
+ * Schedules a recurring recalculation of the total count of users.
+ *
+ * @since 6.0.0
+ */
+function wp_schedule_update_user_counts() {
+ if ( ! is_main_site() ) {
+ return;
+ }
+
+ if ( ! wp_next_scheduled( 'wp_update_user_counts' ) && ! wp_installing() ) {
+ wp_schedule_event( time(), 'twicedaily', 'wp_update_user_counts' );
+ }
+}
+
+/**
+ * Determines whether the site has a large number of users.
+ *
+ * The default criteria for a large site is more than 10,000 users.
+ *
+ * @since 6.0.0
+ *
+ * @param int|null $network_id ID of the network. Default is the current network.
+ * @return bool Whether the site has a large number of users.
+ */
+function wp_is_large_user_count( $network_id = null ) {
+ if ( ! is_multisite() && null !== $network_id ) {
+ _doing_it_wrong( __FUNCTION__, __( 'Unable to pass $network_id if not using multisite.' ), '6.0.0' );
+ }
+ $count = get_user_count( $network_id );
+
+ /**
+ * Filters whether the site is considered large, based on its number of users.
+ *
+ * @since 6.0.0
+ *
+ * @param bool $is_large_user_count Whether the site has a large number of users.
+ * @param int $count The total number of users.
+ * @param int|null $network_id ID of the network. `null` represents the current network.
+ */
+ return apply_filters( 'wp_is_large_user_count', $count > 10000, $count, $network_id );
+}
diff --git a/wp-includes/ms-default-filters.php b/wp-includes/ms-default-filters.php
index 1b32f7a32bd..3411e7dba0e 100644
--- a/wp-includes/ms-default-filters.php
+++ b/wp-includes/ms-default-filters.php
@@ -84,9 +84,14 @@
// Counts.
add_action( 'admin_init', 'wp_schedule_update_network_counts' );
add_action( 'update_network_counts', 'wp_update_network_counts', 10, 0 );
-foreach ( array( 'user_register', 'deleted_user', 'wpmu_new_user', 'make_spam_user', 'make_ham_user' ) as $action ) {
+foreach ( array( 'wpmu_new_user', 'make_spam_user', 'make_ham_user' ) as $action ) {
add_action( $action, 'wp_maybe_update_network_user_counts', 10, 0 );
}
+
+// These counts are handled by wp_update_network_counts() on Multisite:
+remove_action( 'admin_init', 'wp_schedule_update_user_counts' );
+remove_action( 'wp_update_user_counts', 'wp_schedule_update_user_counts' );
+
foreach ( array( 'make_spam_blog', 'make_ham_blog', 'archive_blog', 'unarchive_blog', 'make_delete_blog', 'make_undelete_blog' ) as $action ) {
add_action( $action, 'wp_maybe_update_network_site_counts', 10, 0 );
}
diff --git a/wp-includes/ms-functions.php b/wp-includes/ms-functions.php
index 2059e6da7d0..9e99f7f1a6c 100644
--- a/wp-includes/ms-functions.php
+++ b/wp-includes/ms-functions.php
@@ -100,21 +100,6 @@ function get_active_blog_for_user( $user_id ) {
}
}
-/**
- * The number of active users in your installation.
- *
- * The count is cached and updated twice daily. This is not a live count.
- *
- * @since MU (3.0.0)
- * @since 4.8.0 The `$network_id` parameter has been added.
- *
- * @param int|null $network_id ID of the network. Default is the current network.
- * @return int Number of active users on the network.
- */
-function get_user_count( $network_id = null ) {
- return get_network_option( $network_id, 'user_count' );
-}
-
/**
* The number of active sites on your installation.
*
@@ -2611,16 +2596,12 @@ function wp_update_network_site_counts( $network_id = null ) {
*
* @since 3.7.0
* @since 4.8.0 The `$network_id` parameter has been added.
- *
- * @global wpdb $wpdb WordPress database abstraction object.
+ * @since 6.0.0 This function is now a wrapper for wp_update_user_counts().
*
* @param int|null $network_id ID of the network. Default is the current network.
*/
function wp_update_network_user_counts( $network_id = null ) {
- global $wpdb;
-
- $count = $wpdb->get_var( "SELECT COUNT(ID) as c FROM $wpdb->users WHERE spam = '0' AND deleted = '0'" );
- update_network_option( $network_id, 'user_count', $count );
+ wp_update_user_counts( $network_id );
}
/**
@@ -2754,6 +2735,9 @@ function wp_is_large_network( $using = 'sites', $network_id = null ) {
if ( 'users' === $using ) {
$count = get_user_count( $network_id );
+
+ $is_large_network = wp_is_large_user_count( $network_id );
+
/**
* Filters whether the network is considered large.
*
@@ -2765,7 +2749,7 @@ function wp_is_large_network( $using = 'sites', $network_id = null ) {
* @param int $count The count of items for the component.
* @param int $network_id The ID of the network being checked.
*/
- return apply_filters( 'wp_is_large_network', $count > 10000, 'users', $count, $network_id );
+ return apply_filters( 'wp_is_large_network', $is_large_network, 'users', $count, $network_id );
}
$count = get_blog_count( $network_id );
diff --git a/wp-includes/update.php b/wp-includes/update.php
index e30da7358e1..a18a81e4771 100644
--- a/wp-includes/update.php
+++ b/wp-includes/update.php
@@ -80,13 +80,10 @@ function wp_version_check( $extra_stats = array(), $force_check = false ) {
}
if ( is_multisite() ) {
- $user_count = get_user_count();
$num_blogs = get_blog_count();
$wp_install = network_site_url();
$multisite_enabled = 1;
} else {
- $user_count = count_users();
- $user_count = $user_count['total_users'];
$multisite_enabled = 0;
$num_blogs = 1;
$wp_install = home_url( '/' );
@@ -99,7 +96,7 @@ function wp_version_check( $extra_stats = array(), $force_check = false ) {
'mysql' => $mysql_version,
'local_package' => isset( $wp_local_package ) ? $wp_local_package : '',
'blogs' => $num_blogs,
- 'users' => $user_count,
+ 'users' => get_user_count(),
'multisite_enabled' => $multisite_enabled,
'initial_db_version' => get_site_option( 'initial_db_version' ),
);
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 0bd20606048..a2194e750ef 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
-$wp_version = '6.0-alpha-53010';
+$wp_version = '6.0-alpha-53011';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.