<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[53011] trunk: Users: Introduce the concept of a large site to single site installations.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/53011">53011</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/53011","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>spacedmonkey</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2022-03-29 12:41:00 +0000 (Tue, 29 Mar 2022)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>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 <a href="https://core.trac.wordpress.org/ticket/38741">#38741</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpadminincludesclasswpdebugdataphp">trunk/src/wp-admin/includes/class-wp-debug-data.php</a></li>
<li><a href="#trunksrcwpadminincludesclasswppostslisttablephp">trunk/src/wp-admin/includes/class-wp-posts-list-table.php</a></li>
<li><a href="#trunksrcwpadminincludesclasswpuserslisttablephp">trunk/src/wp-admin/includes/class-wp-users-list-table.php</a></li>
<li><a href="#trunksrcwpadminincludesschemaphp">trunk/src/wp-admin/includes/schema.php</a></li>
<li><a href="#trunksrcwpadminincludesupgradephp">trunk/src/wp-admin/includes/upgrade.php</a></li>
<li><a href="#trunksrcwpincludesdefaultfiltersphp">trunk/src/wp-includes/default-filters.php</a></li>
<li><a href="#trunksrcwpincludesfunctionsphp">trunk/src/wp-includes/functions.php</a></li>
<li><a href="#trunksrcwpincludesmsdefaultfiltersphp">trunk/src/wp-includes/ms-default-filters.php</a></li>
<li><a href="#trunksrcwpincludesmsfunctionsphp">trunk/src/wp-includes/ms-functions.php</a></li>
<li><a href="#trunksrcwpincludesupdatephp">trunk/src/wp-includes/update.php</a></li>
<li><a href="#trunktestsphpunittestsmultisitenetworkphp">trunk/tests/phpunit/tests/multisite/network.php</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunktestsphpunittestsusergetUserCountphp">trunk/tests/phpunit/tests/user/getUserCount.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpadminincludesclasswpdebugdataphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/includes/class-wp-debug-data.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/includes/class-wp-debug-data.php       2022-03-29 11:05:26 UTC (rev 53010)
+++ trunk/src/wp-admin/includes/class-wp-debug-data.php 2022-03-29 12:41:00 UTC (rev 53011)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -388,11 +388,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                $site_count += get_blog_count( $network_id );
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $info['wp-core']['fields']['user_count'] = array(
-                               'label' => __( 'User count' ),
-                               'value' => get_user_count(),
-                       );
-
</del><span class="cx" style="display: block; padding: 0 10px">                         $info['wp-core']['fields']['site_count'] = array(
</span><span class="cx" style="display: block; padding: 0 10px">                                'label' => __( 'Site count' ),
</span><span class="cx" style="display: block; padding: 0 10px">                                'value' => $site_count,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -402,15 +397,13 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                'label' => __( 'Network count' ),
</span><span class="cx" style="display: block; padding: 0 10px">                                'value' => $network_query->found_networks,
</span><span class="cx" style="display: block; padding: 0 10px">                        );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                } else {
-                       $user_count = count_users();
-
-                       $info['wp-core']['fields']['user_count'] = array(
-                               'label' => __( 'User count' ),
-                               'value' => $user_count['total_users'],
-                       );
</del><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $info['wp-core']['fields']['user_count'] = array(
+                       'label' => __( 'User count' ),
+                       'value' => get_user_count(),
+               );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 // WordPress features requiring processing.
</span><span class="cx" style="display: block; padding: 0 10px">                $wp_dotorg = wp_remote_get( 'https://wordpress.org', array( 'timeout' => 10 ) );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpadminincludesclasswppostslisttablephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/includes/class-wp-posts-list-table.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/includes/class-wp-posts-list-table.php 2022-03-29 11:05:26 UTC (rev 53010)
+++ trunk/src/wp-admin/includes/class-wp-posts-list-table.php   2022-03-29 12:41:00 UTC (rev 53011)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1653,7 +1653,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                <?php endif; // $bulk ?>
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                <?php
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                if ( post_type_supports( $screen->post_type, 'author' ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         if ( post_type_supports( $screen->post_type, 'author' ) && ! wp_is_large_user_count() ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                         $authors_dropdown = '';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                        if ( current_user_can( $post_type_object->cap->edit_others_posts ) ) {
</span></span></pre></div>
<a id="trunksrcwpadminincludesclasswpuserslisttablephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/includes/class-wp-users-list-table.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/includes/class-wp-users-list-table.php 2022-03-29 11:05:26 UTC (rev 53010)
+++ trunk/src/wp-admin/includes/class-wp-users-list-table.php   2022-03-29 12:41:00 UTC (rev 53011)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -177,28 +177,33 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $wp_roles = wp_roles();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $count_users = ! wp_is_large_user_count();
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 if ( $this->is_site_users ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $url = 'site-users.php?id=' . $this->site_id;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        switch_to_blog( $this->site_id );
-                       $users_of_blog = count_users( 'time', $this->site_id );
-                       restore_current_blog();
</del><span class="cx" style="display: block; padding: 0 10px">                 } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $url           = 'users.php';
-                       $users_of_blog = count_users();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $url = 'users.php';
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $total_users = $users_of_blog['total_users'];
-               $avail_roles =& $users_of_blog['avail_roles'];
-               unset( $users_of_blog );
-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $role_links              = array();
+               $avail_roles             = array();
+               $all_text                = __( 'All' );
</ins><span class="cx" style="display: block; padding: 0 10px">                 $current_link_attributes = empty( $role ) ? ' class="current" aria-current="page"' : '';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $role_links        = array();
-               $role_links['all'] = sprintf(
-                       '<a href="%s"%s>%s</a>',
-                       $url,
-                       $current_link_attributes,
-                       sprintf(
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         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(
</ins><span class="cx" style="display: block; padding: 0 10px">                                 /* translators: %s: Number of users. */
</span><span class="cx" style="display: block; padding: 0 10px">                                _nx(
</span><span class="cx" style="display: block; padding: 0 10px">                                        'All <span class="count">(%s)</span>',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -207,11 +212,13 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        'users'
</span><span class="cx" style="display: block; padding: 0 10px">                                ),
</span><span class="cx" style="display: block; padding: 0 10px">                                number_format_i18n( $total_users )
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        )
-               );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 );
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $role_links['all'] = sprintf( '<a href="%s"%s>%s</a>', $url, $current_link_attributes, $all_text );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 foreach ( $wp_roles->get_names() as $this_role => $name ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( ! isset( $avail_roles[ $this_role ] ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if ( $count_users && ! isset( $avail_roles[ $this_role ] ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                 continue;
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -222,12 +229,14 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        $name = translate_user_role( $name );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $name = sprintf(
-                               /* translators: 1: User role name, 2: Number of users. */
-                               __( '%1$s <span class="count">(%2$s)</span>' ),
-                               $name,
-                               number_format_i18n( $avail_roles[ $this_role ] )
-                       );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if ( $count_users ) {
+                               $name = sprintf(
+                                       /* translators: 1: User role name, 2: Number of users. */
+                                       __( '%1$s <span class="count">(%2$s)</span>' ),
+                                       $name,
+                                       number_format_i18n( $avail_roles[ $this_role ] )
+                               );
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        $role_links[ $this_role ] = "<a href='" . esc_url( add_query_arg( 'role', $this_role, $url ) ) . "'$current_link_attributes>$name</a>";
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span></span></pre></div>
<a id="trunksrcwpadminincludesschemaphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/includes/schema.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/includes/schema.php    2022-03-29 11:05:26 UTC (rev 53010)
+++ trunk/src/wp-admin/includes/schema.php      2022-03-29 12:41:00 UTC (rev 53011)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1267,6 +1267,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                'subdomain_install'           => $subdomain_install,
</span><span class="cx" style="display: block; padding: 0 10px">                'global_terms_enabled'        => global_terms_enabled() ? '1' : '0',
</span><span class="cx" style="display: block; padding: 0 10px">                'ms_files_rewriting'          => is_multisite() ? get_site_option( 'ms_files_rewriting' ) : '0',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                'user_count'                  => get_site_option( 'user_count' ),
</ins><span class="cx" style="display: block; padding: 0 10px">                 'initial_db_version'          => get_option( 'initial_db_version' ),
</span><span class="cx" style="display: block; padding: 0 10px">                'active_sitewide_plugins'     => array(),
</span><span class="cx" style="display: block; padding: 0 10px">                'WPLANG'                      => get_locale(),
</span></span></pre></div>
<a id="trunksrcwpadminincludesupgradephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/includes/upgrade.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/includes/upgrade.php   2022-03-29 11:05:26 UTC (rev 53010)
+++ trunk/src/wp-admin/includes/upgrade.php     2022-03-29 12:41:00 UTC (rev 53011)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -845,6 +845,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">                upgrade_590();
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        if ( $wp_current_db_version < 53011 ) {
+               upgrade_600();
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         maybe_disable_link_manager();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        maybe_disable_automattic_widgets();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2283,6 +2287,22 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * 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();
+       }
+}
+
+/**
</ins><span class="cx" style="display: block; padding: 0 10px">  * Executes network-level upgrade routines.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 3.0.0
</span></span></pre></div>
<a id="trunksrcwpincludesdefaultfiltersphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/default-filters.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/default-filters.php 2022-03-29 11:05:26 UTC (rev 53010)
+++ trunk/src/wp-includes/default-filters.php   2022-03-29 12:41:00 UTC (rev 53011)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -98,6 +98,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // Meta.
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'register_meta_args', '_wp_register_meta_args_allowed_list', 10, 2 );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+// 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 );
+}
+
</ins><span class="cx" style="display: block; padding: 0 10px"> // Post meta.
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'added_post_meta', 'wp_cache_set_posts_last_changed' );
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'updated_post_meta', 'wp_cache_set_posts_last_changed' );
</span></span></pre></div>
<a id="trunksrcwpincludesfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/functions.php       2022-03-29 11:05:26 UTC (rev 53010)
+++ trunk/src/wp-includes/functions.php 2022-03-29 12:41:00 UTC (rev 53011)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -8418,3 +8418,113 @@
</span><span class="cx" style="display: block; padding: 0 10px"> function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) {
</span><span class="cx" style="display: block; padding: 0 10px">        return abs( (float) $expected - (float) $actual ) <= $precision;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+/**
+ * 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 );
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesmsdefaultfiltersphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ms-default-filters.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ms-default-filters.php      2022-03-29 11:05:26 UTC (rev 53010)
+++ trunk/src/wp-includes/ms-default-filters.php        2022-03-29 12:41:00 UTC (rev 53011)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -84,9 +84,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // Counts.
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'admin_init', 'wp_schedule_update_network_counts' );
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'update_network_counts', 'wp_update_network_counts', 10, 0 );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-foreach ( array( 'user_register', 'deleted_user', 'wpmu_new_user', 'make_spam_user', 'make_ham_user' ) as $action ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+foreach ( array( 'wpmu_new_user', 'make_spam_user', 'make_ham_user' ) as $action ) {
</ins><span class="cx" style="display: block; padding: 0 10px">         add_action( $action, 'wp_maybe_update_network_user_counts', 10, 0 );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+// 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' );
+
</ins><span class="cx" style="display: block; padding: 0 10px"> foreach ( array( 'make_spam_blog', 'make_ham_blog', 'archive_blog', 'unarchive_blog', 'make_delete_blog', 'make_undelete_blog' ) as $action ) {
</span><span class="cx" style="display: block; padding: 0 10px">        add_action( $action, 'wp_maybe_update_network_site_counts', 10, 0 );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesmsfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ms-functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ms-functions.php    2022-03-29 11:05:26 UTC (rev 53010)
+++ trunk/src/wp-includes/ms-functions.php      2022-03-29 12:41:00 UTC (rev 53011)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -101,21 +101,6 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * 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' );
-}
-
-/**
</del><span class="cx" style="display: block; padding: 0 10px">  * The number of active sites on your installation.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * The count is cached and updated twice daily. This is not a live count.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2611,16 +2596,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 3.7.0
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 4.8.0 The `$network_id` parameter has been added.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 6.0.0 This function is now a wrapper for wp_update_user_counts().
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @global wpdb $wpdb WordPress database abstraction object.
- *
</del><span class="cx" style="display: block; padding: 0 10px">  * @param int|null $network_id ID of the network. Default is the current network.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function wp_update_network_user_counts( $network_id = null ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        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 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ wp_update_user_counts( $network_id );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2754,6 +2735,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        if ( 'users' === $using ) {
</span><span class="cx" style="display: block; padding: 0 10px">                $count = get_user_count( $network_id );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+               $is_large_network = wp_is_large_user_count( $network_id );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 /**
</span><span class="cx" style="display: block; padding: 0 10px">                 * Filters whether the network is considered large.
</span><span class="cx" style="display: block; padding: 0 10px">                 *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2765,7 +2749,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                 * @param int    $count            The count of items for the component.
</span><span class="cx" style="display: block; padding: 0 10px">                 * @param int    $network_id       The ID of the network being checked.
</span><span class="cx" style="display: block; padding: 0 10px">                 */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                return apply_filters( 'wp_is_large_network', $count > 10000, 'users', $count, $network_id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         return apply_filters( 'wp_is_large_network', $is_large_network, 'users', $count, $network_id );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $count = get_blog_count( $network_id );
</span></span></pre></div>
<a id="trunksrcwpincludesupdatephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/update.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/update.php  2022-03-29 11:05:26 UTC (rev 53010)
+++ trunk/src/wp-includes/update.php    2022-03-29 12:41:00 UTC (rev 53011)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -80,13 +80,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        if ( is_multisite() ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $user_count        = get_user_count();
</del><span class="cx" style="display: block; padding: 0 10px">                 $num_blogs         = get_blog_count();
</span><span class="cx" style="display: block; padding: 0 10px">                $wp_install        = network_site_url();
</span><span class="cx" style="display: block; padding: 0 10px">                $multisite_enabled = 1;
</span><span class="cx" style="display: block; padding: 0 10px">        } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $user_count        = count_users();
-               $user_count        = $user_count['total_users'];
</del><span class="cx" style="display: block; padding: 0 10px">                 $multisite_enabled = 0;
</span><span class="cx" style="display: block; padding: 0 10px">                $num_blogs         = 1;
</span><span class="cx" style="display: block; padding: 0 10px">                $wp_install        = home_url( '/' );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -99,7 +96,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                'mysql'              => $mysql_version,
</span><span class="cx" style="display: block; padding: 0 10px">                'local_package'      => isset( $wp_local_package ) ? $wp_local_package : '',
</span><span class="cx" style="display: block; padding: 0 10px">                'blogs'              => $num_blogs,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                'users'              => $user_count,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         'users'              => get_user_count(),
</ins><span class="cx" style="display: block; padding: 0 10px">                 'multisite_enabled'  => $multisite_enabled,
</span><span class="cx" style="display: block; padding: 0 10px">                'initial_db_version' => get_site_option( 'initial_db_version' ),
</span><span class="cx" style="display: block; padding: 0 10px">        );
</span></span></pre></div>
<a id="trunktestsphpunittestsmultisitenetworkphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/multisite/network.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/multisite/network.php   2022-03-29 11:05:26 UTC (rev 53010)
+++ trunk/tests/phpunit/tests/multisite/network.php     2022-03-29 12:41:00 UTC (rev 53011)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -205,55 +205,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->assertEquals( count( self::$different_site_ids ), $site_count );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                /**
-                * @ticket 37866
-                */
-               public function test_get_user_count_on_different_network() {
-                       wp_update_network_user_counts();
-                       $current_network_user_count = get_user_count();
</del><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        // Add another user to fake the network user count to be different.
-                       wpmu_create_user( 'user', 'pass', 'email' );
</del><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        wp_update_network_user_counts( self::$different_network_id );
-
-                       $user_count = get_user_count( self::$different_network_id );
-
-                       $this->assertEquals( $current_network_user_count + 1, $user_count );
-               }
-
-               /**
-                * @ticket 22917
-                */
-               public function test_enable_live_network_user_counts_filter() {
-                       // False for large networks by default.
-                       add_filter( 'enable_live_network_counts', '__return_false' );
-
-                       // Refresh the cache.
-                       wp_update_network_counts();
-                       $start_count = get_user_count();
-
-                       wpmu_create_user( 'user', 'pass', 'email' );
-
-                       // No change, cache not refreshed.
-                       $count = get_user_count();
-
-                       $this->assertSame( $start_count, $count );
-
-                       wp_update_network_counts();
-                       $start_count = get_user_count();
-
-                       add_filter( 'enable_live_network_counts', '__return_true' );
-
-                       wpmu_create_user( 'user2', 'pass2', 'email2' );
-
-                       $count = get_user_count();
-                       $this->assertEquals( $start_count + 1, $count );
-
-                       remove_filter( 'enable_live_network_counts', '__return_false' );
-                       remove_filter( 'enable_live_network_counts', '__return_true' );
-               }
-
</del><span class="cx" style="display: block; padding: 0 10px">                 public function test_active_network_plugins() {
</span><span class="cx" style="display: block; padding: 0 10px">                        $path = 'hello.php';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -319,25 +272,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->plugin_hook_count++;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                public function test_get_user_count() {
-                       // Refresh the cache.
-                       wp_update_network_counts();
-                       $start_count = get_user_count();
-
-                       // Only false for large networks as of 3.7.
-                       add_filter( 'enable_live_network_counts', '__return_false' );
-                       self::factory()->user->create( array( 'role' => 'administrator' ) );
-
-                       $count = get_user_count(); // No change, cache not refreshed.
-                       $this->assertSame( $start_count, $count );
-
-                       wp_update_network_counts(); // Magic happens here.
-
-                       $count = get_user_count();
-                       $this->assertEquals( $start_count + 1, $count );
-                       remove_filter( 'enable_live_network_counts', '__return_false' );
-               }
-
</del><span class="cx" style="display: block; padding: 0 10px">                 public function test_wp_schedule_update_network_counts() {
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->assertFalse( wp_next_scheduled( 'update_network_counts' ) );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -407,7 +341,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        update_network_option( null, 'user_count', 40 );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $expected = $wpdb->get_var( "SELECT COUNT(ID) as c FROM $wpdb->users WHERE spam = '0' AND deleted = '0'" );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $expected = (int) $wpdb->get_var( "SELECT COUNT(ID) as c FROM $wpdb->users WHERE spam = '0' AND deleted = '0'" );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        wp_update_network_user_counts();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -423,7 +357,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        update_network_option( self::$different_network_id, 'user_count', 40 );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $expected = $wpdb->get_var( "SELECT COUNT(ID) as c FROM $wpdb->users WHERE spam = '0' AND deleted = '0'" );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $expected = (int) $wpdb->get_var( "SELECT COUNT(ID) as c FROM $wpdb->users WHERE spam = '0' AND deleted = '0'" );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        wp_update_network_user_counts( self::$different_network_id );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunktestsphpunittestsusergetUserCountphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/tests/phpunit/tests/user/getUserCount.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/user/getUserCount.php                           (rev 0)
+++ trunk/tests/phpunit/tests/user/getUserCount.php     2022-03-29 12:41:00 UTC (rev 53011)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,171 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * @group user
+ * @covers ::get_user_count
+ */
+class Tests_User_GetUserCount extends WP_UnitTestCase {
+       /**
+        * @ticket 40386
+        * @group multisite
+        * @group ms-required
+        */
+       public function test_wp_update_network_counts_on_different_network() {
+               $this->skipWithoutMultisite();
+               $different_network_id = self::factory()->network->create(
+                       array(
+                               'domain' => 'wordpress.org',
+                               'path'   => '/',
+                       )
+               );
+
+               delete_network_option( $different_network_id, 'user_count' );
+
+               wp_update_network_counts( $different_network_id );
+
+               $user_count = get_user_count( $different_network_id );
+
+               $this->assertGreaterThan( 0, $user_count );
+       }
+
+       /**
+        * @ticket 37866
+        * @group multisite
+        * @group ms-required
+        */
+       public function test_get_user_count_on_different_network() {
+               $this->skipWithoutMultisite();
+               $different_network_id = self::factory()->network->create(
+                       array(
+                               'domain' => 'wordpress.org',
+                               'path'   => '/',
+                       )
+               );
+               wp_update_network_user_counts();
+               $current_network_user_count = get_user_count();
+
+               // Add another user to fake the network user count to be different.
+               wpmu_create_user( 'user', 'pass', 'email' );
+
+               wp_update_network_user_counts( $different_network_id );
+
+               $user_count = get_user_count( $different_network_id );
+
+               $this->assertSame( $current_network_user_count + 1, $user_count );
+       }
+
+       /**
+        * @ticket 22917
+        * @group multisite
+        * @group ms-required
+        */
+       public function test_enable_live_network_user_counts_filter() {
+               $this->skipWithoutMultisite();
+               // False for large networks by default.
+               add_filter( 'enable_live_network_counts', '__return_false' );
+
+               // Refresh the cache.
+               wp_update_network_counts();
+               $start_count = get_user_count();
+
+               wpmu_create_user( 'user', 'pass', 'email' );
+
+               // No change, cache not refreshed.
+               $count = get_user_count();
+
+               $this->assertSame( $start_count, $count );
+
+               wp_update_network_counts();
+               $start_count = get_user_count();
+
+               add_filter( 'enable_live_network_counts', '__return_true' );
+
+               self::factory()->user->create( array( 'role' => 'administrator' ) );
+
+               $count = get_user_count();
+               $this->assertSame( $start_count + 1, $count );
+
+       }
+
+       /**
+        * @ticket 38741
+        */
+       public function test_get_user_count_update() {
+               wp_update_user_counts();
+               $current_network_user_count = get_user_count();
+
+               self::factory()->user->create( array( 'role' => 'administrator' ) );
+
+               $user_count = get_user_count();
+
+               $this->assertSame( $current_network_user_count + 1, $user_count );
+       }
+
+       /**
+        * @group ms-excluded
+        * @ticket 38741
+        */
+       public function test_get_user_count_update_on_delete() {
+               $this->skipWithMultisite();
+               wp_update_user_counts();
+               $current_network_user_count = get_user_count();
+
+               $u1 = self::factory()->user->create( array( 'role' => 'administrator' ) );
+
+               $user_count = get_user_count();
+
+               $this->assertSame( $current_network_user_count + 1, $user_count );
+
+               wp_delete_user( $u1 );
+
+               $user_count_after_delete = get_user_count();
+
+               $this->assertSame( $user_count - 1, $user_count_after_delete );
+       }
+
+       /**
+        * @group ms-required
+        * @ticket 38741
+        */
+       public function test_get_user_count_update_on_delete_multisite() {
+               $this->skipWithoutMultisite();
+               wp_update_user_counts();
+               $current_network_user_count = get_user_count();
+
+               $u1 = wpmu_create_user( 'user', 'pass', 'email' );
+
+               $user_count = get_user_count();
+
+               $this->assertSame( $current_network_user_count + 1, $user_count );
+
+               wpmu_delete_user( $u1 );
+
+               $user_count_after_delete = get_user_count();
+
+               $this->assertSame( $user_count - 1, $user_count_after_delete );
+       }
+
+       /**
+        * @group multisite
+        * @group ms-required
+        * @ticket 38741
+        */
+       public function test_get_user_count() {
+               $this->skipWithoutMultisite();
+               // Refresh the cache.
+               wp_update_network_counts();
+               $start_count = get_user_count();
+
+               // Only false for large networks as of 3.7.
+               add_filter( 'enable_live_network_counts', '__return_false' );
+               self::factory()->user->create( array( 'role' => 'administrator' ) );
+
+               $count = get_user_count(); // No change, cache not refreshed.
+               $this->assertSame( $start_count, $count );
+
+               wp_update_network_counts(); // Magic happens here.
+
+               $count = get_user_count();
+               $this->assertSame( $start_count + 1, $count );
+       }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/tests/phpunit/tests/user/getUserCount.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span></div>

</body>
</html>