diff --git a/src/wp-includes/ms-default-filters.php b/src/wp-includes/ms-default-filters.php index 9d5da57f3e..759c81f0ed 100644 --- a/src/wp-includes/ms-default-filters.php +++ b/src/wp-includes/ms-default-filters.php @@ -37,8 +37,15 @@ add_filter( 'term_id_filter', 'global_terms', 10, 2 ); add_action( 'publish_post', 'update_posts_count' ); add_action( 'delete_post', '_update_blog_date_on_post_delete' ); add_action( 'transition_post_status', '_update_blog_date_on_post_publish', 10, 3 ); + +// Counts add_action( 'admin_init', 'wp_schedule_update_network_counts'); add_action( 'update_network_counts', 'wp_update_network_counts'); +foreach ( array( 'user_register', 'deleted_user', 'wpmu_new_user', 'make_spam_user', 'make_ham_user' ) as $action ) + add_action( $action, 'wp_maybe_update_network_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' ); +unset( $action ); // Files add_filter( 'wp_upload_bits', 'upload_is_file_too_big' ); diff --git a/src/wp-includes/ms-functions.php b/src/wp-includes/ms-functions.php index 0ec664b065..6620998edc 100644 --- a/src/wp-includes/ms-functions.php +++ b/src/wp-includes/ms-functions.php @@ -1102,6 +1102,9 @@ function insert_blog($domain, $path, $site_id) { $blog_id = $wpdb->insert_id; refresh_blog_details( $blog_id ); + + wp_maybe_update_network_site_counts(); + return $blog_id; } @@ -1876,10 +1879,83 @@ function wp_schedule_update_network_counts() { * @since 3.1.0 */ function wp_update_network_counts() { + wp_update_network_user_counts(); + wp_update_network_site_counts(); +} + +/** + * Update the count of sites for the current network. + * + * If enabled through the 'enable_live_network_counts' filter, update the sites count + * on a network when a site is created or its status is updated. + * + * @since 3.7.0 + * + * @uses wp_update_network_site_counts() + */ +function wp_maybe_update_network_site_counts() { + $is_small_network = ! wp_is_large_network( 'sites' ); + + /** + * Filter the decision to update network user and site counts in real time. + * + * @since 3.7.0 + * + * @param bool $small_network Based on wp_is_large_network( $context ). + * @param string $context Context. Either 'users' or 'sites'. + */ + if ( ! apply_filters( 'enable_live_network_counts', $is_small_network, 'sites' ) ) + return; + + wp_update_network_site_counts(); +} + +/** + * Update the network-wide users count. + * + * If enabled through the 'enable_live_network_counts' filter, update the users count + * on a network when a user is created or its status is updated. + * + * @since 3.7.0 + * + * @uses wp_update_network_user_counts() + */ +function wp_maybe_update_network_user_counts() { + $is_small_network = ! wp_is_large_network( 'users' ); + + /** + * Filter the decision to update network user and site counts in real time. + * + * @since 3.7.0 + * + * @param bool $small_network Based on wp_is_large_network( $context ). + * @param string $context Context. Either 'users' or 'sites'. + */ + if ( ! apply_filters( 'enable_live_network_counts', $is_small_network, 'users' ) ) + return; + + wp_update_network_user_counts(); +} + +/** + * Update the network-wide site count. + * + * @since 3.7.0 + */ +function wp_update_network_site_counts() { global $wpdb; $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(blog_id) as c FROM $wpdb->blogs WHERE site_id = %d AND spam = '0' AND deleted = '0' and archived = '0'", $wpdb->siteid) ); update_site_option( 'blog_count', $count ); +} + +/** + * Update the network-wide user count. + * + * @since 3.7.0 + */ +function wp_update_network_user_counts() { + global $wpdb; $count = $wpdb->get_var( "SELECT COUNT(ID) as c FROM $wpdb->users WHERE spam = '0' AND deleted = '0'" ); update_site_option( 'user_count', $count ); diff --git a/tests/phpunit/tests/ms.php b/tests/phpunit/tests/ms.php index b95a12207c..34c35a00b1 100644 --- a/tests/phpunit/tests/ms.php +++ b/tests/phpunit/tests/ms.php @@ -16,6 +16,63 @@ class Tests_MS extends WP_UnitTestCase { $_SERVER['REMOTE_ADDR'] = ''; } + /** + * @ticket 22917 + */ + function test_enable_live_network_site_counts_filter() { + $site_count_start = get_blog_count(); + // false for large networks by default + add_filter( 'enable_live_network_counts', '__return_false' ); + $this->factory->blog->create_many( 4 ); + + // count only updated when cron runs, so unchanged + $this->assertEquals( $site_count_start, (int) get_blog_count() ); + + add_filter( 'enable_live_network_counts', '__return_true' ); + $site_ids = $this->factory->blog->create_many( 4 ); + + $this->assertEquals( $site_count_start + 9, (int) get_blog_count() ); + + //clean up + remove_filter( 'enable_live_network_counts', '__return_false' ); + remove_filter( 'enable_live_network_counts', '__return_true' ); + foreach ( $site_ids as $site_id ) { + wpmu_delete_blog( $site_id, true ); + } + } + + /** + * @ticket 22917 + */ + 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->assertEquals( $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' ); + } + function test_create_and_delete_blog() { global $wpdb; @@ -230,6 +287,8 @@ class Tests_MS extends WP_UnitTestCase { 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' ); $this->factory->user->create( array( 'role' => 'administrator' ) ); $count = get_user_count(); // No change, cache not refreshed @@ -239,6 +298,7 @@ class Tests_MS extends WP_UnitTestCase { $count = get_user_count(); $this->assertEquals( $start_count + 1, $count ); + remove_filter( 'enable_live_network_counts', '__return_false' ); } function test_wp_schedule_update_network_counts() {