diff --git a/src/wp-admin/includes/class-wp-ms-sites-list-table.php b/src/wp-admin/includes/class-wp-ms-sites-list-table.php index 1ffa24ea24106..37cc0d3487d02 100644 --- a/src/wp-admin/includes/class-wp-ms-sites-list-table.php +++ b/src/wp-admin/includes/class-wp-ms-sites-list-table.php @@ -47,6 +47,8 @@ public function __construct( $args = array() ) { 'screen' => $args['screen'] ?? null, ) ); + + add_filter( 'hidden_columns', array( $this, 'hide_site_admin_email_column' ), 10, 2 ); } /** @@ -382,11 +384,12 @@ protected function extra_tablenav( $which ) { */ public function get_columns() { $sites_columns = array( - 'cb' => '', - 'blogname' => __( 'URL' ), - 'lastupdated' => __( 'Last Updated' ), - 'registered' => _x( 'Registered', 'site' ), - 'users' => __( 'Users' ), + 'cb' => '', + 'blogname' => __( 'URL' ), + 'site_admin_email' => __( 'Admin Email' ), + 'lastupdated' => __( 'Last Updated' ), + 'registered' => _x( 'Registered', 'site' ), + 'users' => __( 'Users' ), ); if ( has_filter( 'wpmublogsaction' ) ) { @@ -399,11 +402,44 @@ public function get_columns() { * @since MU (3.0.0) * * @param string[] $sites_columns An array of displayed site columns. Default 'cb', - * 'blogname', 'lastupdated', 'registered', 'users'. + * 'blogname', 'site_admin_email', 'lastupdated', + * 'registered', 'users'. */ return apply_filters( 'wpmu_blogs_columns', $sites_columns ); } + /** + * Hides the site admin email column until the user changes their screen options. + * + * @since 7.2.0 + * + * @param string[] $hidden An array of hidden columns. + * @param WP_Screen $screen The current screen object. + * @return string[] An array of hidden columns. + */ + public function hide_site_admin_email_column( $hidden, $screen ) { + $user_id = get_current_user_id(); + if ( ! $user_id || $this->screen->id !== $screen->id ) { + return $hidden; + } + + $hidden_option = 'manage' . $screen->id . 'columnshidden'; + $initialized_option = $hidden_option . '_site_admin_email_initialized'; + + if ( get_user_meta( $user_id, $initialized_option, true ) ) { + return $hidden; + } + + if ( ! in_array( 'site_admin_email', $hidden, true ) ) { + $hidden[] = 'site_admin_email'; + } + + update_user_meta( $user_id, $hidden_option, $hidden ); + update_user_meta( $user_id, $initialized_option, true ); + + return $hidden; + } + /** * Gets an array of sortable columns. * @@ -508,6 +544,21 @@ public function column_blogname( $blog ) { } } + /** + * Handles the admin email column output. + * + * @since 7.2.0 + * + * @param array $blog Current site. + */ + public function column_site_admin_email( $blog ) { + list( , $hidden ) = $this->get_column_info(); + + if ( ! in_array( 'site_admin_email', $hidden, true ) ) { + echo esc_html( get_blog_option( $blog['blog_id'], 'admin_email' ) ); + } + } + /** * Handles the lastupdated column output. * diff --git a/tests/phpunit/tests/multisite/wpMsSitesListTable.php b/tests/phpunit/tests/multisite/wpMsSitesListTable.php index e485cd3bbefef..08fa5eb407d70 100644 --- a/tests/phpunit/tests/multisite/wpMsSitesListTable.php +++ b/tests/phpunit/tests/multisite/wpMsSitesListTable.php @@ -96,6 +96,110 @@ public function test_ms_sites_list_table_default_items() { $this->assertSameSets( array( 1 ) + self::$site_ids, $items ); } + /** + * @ticket 33832 + */ + public function test_ms_sites_list_table_admin_email_column_does_not_load_when_hidden() { + $hide_admin_email = static function ( $hidden ) { + $hidden[] = 'site_admin_email'; + return $hidden; + }; + add_filter( 'hidden_columns', $hide_admin_email ); + + $table = _get_list_table( 'WP_MS_Sites_List_Table', array( 'screen' => 'ms-sites' ) ); + $admin_email_requested = false; + $track_option_request = static function ( $value ) use ( &$admin_email_requested ) { + $admin_email_requested = true; + return $value; + }; + add_filter( 'pre_option_admin_email', $track_option_request ); + + ob_start(); + $table->column_site_admin_email( array( 'blog_id' => self::$site_ids['wordpress.org/foo/'] ) ); + $output = ob_get_clean(); + + remove_filter( 'hidden_columns', $hide_admin_email ); + remove_filter( 'pre_option_admin_email', $track_option_request ); + + $this->assertSame( '', $output ); + $this->assertFalse( $admin_email_requested ); + } + + /** + * @ticket 33832 + */ + public function test_ms_sites_list_table_admin_email_column_is_opt_in_for_existing_preferences() { + $user_id = self::factory()->user->create(); + $screen_id = 'ms-sites-admin-email-preferences'; + $hidden_option = 'manage' . $screen_id . 'columnshidden'; + + wp_set_current_user( $user_id ); + update_user_meta( $user_id, $hidden_option, array( 'registered' ) ); + + $table = _get_list_table( 'WP_MS_Sites_List_Table', array( 'screen' => $screen_id ) ); + $hidden = get_hidden_columns( $table->screen ); + + $this->assertSame( array( 'registered', 'site_admin_email' ), $hidden ); + $this->assertSame( $hidden, get_user_meta( $user_id, $hidden_option, true ) ); + + // Enabling the column through Screen Options must persist. + update_user_meta( $user_id, $hidden_option, array( 'registered' ) ); + $table = _get_list_table( 'WP_MS_Sites_List_Table', array( 'screen' => $screen_id ) ); + + $this->assertSame( array( 'registered' ), get_hidden_columns( $table->screen ) ); + + wp_set_current_user( 0 ); + } + + /** + * @ticket 33832 + */ + public function test_ms_sites_list_table_admin_email_column_output() { + $site_id = self::$site_ids['wordpress.org/foo/']; + $admin_email = 'site-admin@example.org'; + + update_blog_option( $site_id, 'admin_email', $admin_email ); + + $this->assertArrayHasKey( 'site_admin_email', $this->table->get_columns() ); + + ob_start(); + $this->table->column_site_admin_email( array( 'blog_id' => $site_id ) ); + $output = ob_get_clean(); + + $this->assertSame( $admin_email, $output ); + } + + /** + * @ticket 33832 + */ + public function test_existing_admin_email_custom_column_uses_custom_column_hook() { + $add_admin_email_column = static function ( $columns ) { + $columns['admin_email'] = 'Custom Admin Email'; + return $columns; + }; + $custom_column_rendered = false; + $render_admin_email_column = static function ( $column_name ) use ( &$custom_column_rendered ) { + if ( 'admin_email' === $column_name ) { + $custom_column_rendered = true; + } + }; + + add_filter( 'wpmu_blogs_columns', $add_admin_email_column ); + add_action( 'manage_sites_custom_column', $render_admin_email_column ); + + $table = _get_list_table( 'WP_MS_Sites_List_Table', array( 'screen' => 'ms-sites-admin-email-compat' ) ); + $table->items = array( get_site( self::$site_ids['wordpress.org/foo/'] ) ); + + ob_start(); + $table->display_rows(); + ob_end_clean(); + + remove_filter( 'wpmu_blogs_columns', $add_admin_email_column ); + remove_action( 'manage_sites_custom_column', $render_admin_email_column ); + + $this->assertTrue( $custom_column_rendered ); + } + public function test_ms_sites_list_table_subdirectory_path_search_items() { if ( is_subdomain_install() ) { $this->markTestSkipped( 'Path search is not available for subdomain configurations.' );