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.' );