diff -r 3d4e9c994f10 -r a86126ab1dd4 wp/wp-admin/includes/class-wp-ms-sites-list-table.php --- a/wp/wp-admin/includes/class-wp-ms-sites-list-table.php Tue Oct 22 16:11:46 2019 +0200 +++ b/wp/wp-admin/includes/class-wp-ms-sites-list-table.php Tue Dec 15 13:49:49 2020 +0100 @@ -62,15 +62,15 @@ * * @since 3.1.0 * + * @global string $mode List table view mode. * @global string $s - * @global string $mode - * @global wpdb $wpdb + * @global wpdb $wpdb WordPress database abstraction object. */ public function prepare_items() { - global $s, $mode, $wpdb; + global $mode, $s, $wpdb; if ( ! empty( $_REQUEST['mode'] ) ) { - $mode = $_REQUEST['mode'] === 'excerpt' ? 'excerpt' : 'list'; + $mode = 'excerpt' === $_REQUEST['mode'] ? 'excerpt' : 'list'; set_user_setting( 'sites_list_mode', $mode ); } else { $mode = get_user_setting( 'sites_list_mode', 'list' ); @@ -93,10 +93,12 @@ */ if ( ! $s && wp_is_large_network() ) { if ( ! isset( $_REQUEST['orderby'] ) ) { - $_GET['orderby'] = $_REQUEST['orderby'] = ''; + $_GET['orderby'] = ''; + $_REQUEST['orderby'] = ''; } if ( ! isset( $_REQUEST['order'] ) ) { - $_GET['order'] = $_REQUEST['order'] = 'DESC'; + $_GET['order'] = 'DESC'; + $_REQUEST['order'] = 'DESC'; } } @@ -112,7 +114,7 @@ preg_match( '/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.?$/', $s ) || preg_match( '/^[0-9]{1,3}\.[0-9]{1,3}\.?$/', $s ) || preg_match( '/^[0-9]{1,3}\.$/', $s ) ) { - // IPv4 address + // IPv4 address. $sql = $wpdb->prepare( "SELECT blog_id FROM {$wpdb->registration_log} WHERE {$wpdb->registration_log}.IP LIKE %s", $wpdb->esc_like( $s ) . ( ! empty( $wild ) ? '%' : '' ) ); $reg_blog_ids = $wpdb->get_col( $sql ); @@ -131,7 +133,7 @@ $order_by = isset( $_REQUEST['orderby'] ) ? $_REQUEST['orderby'] : ''; if ( 'registered' === $order_by ) { - // registered is a valid field name. + // 'registered' is a valid field name. } elseif ( 'lastupdated' === $order_by ) { $order_by = 'last_updated'; } elseif ( 'blogname' === $order_by ) { @@ -158,6 +160,12 @@ $args['no_found_rows'] = false; } + // Take into account the role the user has selected. + $status = isset( $_REQUEST['status'] ) ? wp_unslash( trim( $_REQUEST['status'] ) ) : ''; + if ( in_array( $status, array( 'public', 'archived', 'mature', 'spam', 'deleted' ), true ) ) { + $args[ $status ] = 1; + } + /** * Filters the arguments for the site query in the sites list table. * @@ -200,6 +208,80 @@ } /** + * Gets links to filter sites by status. + * + * @since 5.3.0 + * + * @return array + */ + protected function get_views() { + $counts = wp_count_sites(); + + $statuses = array( + /* translators: %s: Number of sites. */ + 'all' => _nx_noop( + 'All (%s)', + 'All (%s)', + 'sites' + ), + + /* translators: %s: Number of sites. */ + 'public' => _n_noop( + 'Public (%s)', + 'Public (%s)' + ), + + /* translators: %s: Number of sites. */ + 'archived' => _n_noop( + 'Archived (%s)', + 'Archived (%s)' + ), + + /* translators: %s: Number of sites. */ + 'mature' => _n_noop( + 'Mature (%s)', + 'Mature (%s)' + ), + + /* translators: %s: Number of sites. */ + 'spam' => _nx_noop( + 'Spam (%s)', + 'Spam (%s)', + 'sites' + ), + + /* translators: %s: Number of sites. */ + 'deleted' => _n_noop( + 'Deleted (%s)', + 'Deleted (%s)' + ), + ); + + $view_links = array(); + $requested_status = isset( $_REQUEST['status'] ) ? wp_unslash( trim( $_REQUEST['status'] ) ) : ''; + $url = 'sites.php'; + + foreach ( $statuses as $status => $label_count ) { + $current_link_attributes = $requested_status === $status || ( '' === $requested_status && 'all' === $status ) + ? ' class="current" aria-current="page"' + : ''; + if ( (int) $counts[ $status ] > 0 ) { + $label = sprintf( translate_nooped_plural( $label_count, $counts[ $status ] ), number_format_i18n( $counts[ $status ] ) ); + $full_url = 'all' === $status ? $url : add_query_arg( 'status', $status, $url ); + + $view_links[ $status ] = sprintf( + '%3$s', + esc_url( $full_url ), + $current_link_attributes, + $label + ); + } + } + + return $view_links; + } + + /** * @return array */ protected function get_bulk_actions() { @@ -207,8 +289,8 @@ if ( current_user_can( 'delete_sites' ) ) { $actions['delete'] = __( 'Delete' ); } - $actions['spam'] = _x( 'Mark as Spam', 'site' ); - $actions['notspam'] = _x( 'Not Spam', 'site' ); + $actions['spam'] = _x( 'Mark as spam', 'site' ); + $actions['notspam'] = _x( 'Not spam', 'site' ); return $actions; } @@ -216,7 +298,7 @@ /** * @global string $mode List table view mode. * - * @param string $which + * @param string $which The location of the pagination nav markup: 'top' or 'bottom'. */ protected function pagination( $which ) { global $mode; @@ -229,6 +311,48 @@ } /** + * Extra controls to be displayed between bulk actions and pagination. + * + * @since 5.3.0 + * + * @param string $which The location of the extra table nav markup: 'top' or 'bottom'. + */ + protected function extra_tablenav( $which ) { + ?> +
+ 'site-query-submit' ) ); + } + } + ?> +
+ status_list ); - - foreach ( $this->status_list as $status => $col ) { - if ( $blog[ $status ] == 1 ) { - $blog_states[] = $col[1]; - } - } - $blog_state = ''; - if ( ! empty( $blog_states ) ) { - $state_count = count( $blog_states ); - $i = 0; - $blog_state .= ' — '; - foreach ( $blog_states as $state ) { - ++$i; - $sep = ( $i == $state_count ) ? '' : ', '; - $blog_state .= "$state$sep"; - } - } + $blogname = untrailingslashit( $blog['domain'] . $blog['path'] ); ?> - + site_states( $blog ); ?> '; printf( - /* translators: 1: site name, 2: site tagline. */ + /* translators: 1: Site title, 2: Site tagline. */ __( '%1$s – %2$s' ), get_option( 'blogname' ), - '' . get_option( 'blogdescription ' ) . '' + '' . get_option( 'blogdescription' ) . '' ); echo '

'; restore_current_blog(); @@ -369,7 +475,7 @@ $date = __( 'Y/m/d g:i:s a' ); } - echo ( $blog['last_updated'] === '0000-00-00 00:00:00' ) ? __( 'Never' ) : mysql2date( $date, $blog['last_updated'] ); + echo ( '0000-00-00 00:00:00' === $blog['last_updated'] ) ? __( 'Never' ) : mysql2date( $date, $blog['last_updated'] ); } /** @@ -390,7 +496,7 @@ $date = __( 'Y/m/d g:i:s a' ); } - if ( $blog['registered'] === '0000-00-00 00:00:00' ) { + if ( '0000-00-00 00:00:00' === $blog['registered'] ) { echo '—'; } else { echo mysql2date( $date, $blog['registered'] ); @@ -469,7 +575,7 @@ } /** - * @global string $mode + * @global string $mode List table view mode. */ public function display_rows() { foreach ( $this->items as $blog ) { @@ -478,7 +584,7 @@ reset( $this->status_list ); foreach ( $this->status_list as $status => $col ) { - if ( $blog[ $status ] == 1 ) { + if ( 1 == $blog[ $status ] ) { $class = " class='{$col[0]}'"; } } @@ -492,6 +598,55 @@ } /** + * Maybe output comma-separated site states. + * + * @since 5.3.0 + * + * @param array $site + */ + protected function site_states( $site ) { + $site_states = array(); + + // $site is still an array, so get the object. + $_site = WP_Site::get_instance( $site['blog_id'] ); + + if ( is_main_site( $_site->id ) ) { + $site_states['main'] = __( 'Main' ); + } + + reset( $this->status_list ); + + $site_status = isset( $_REQUEST['status'] ) ? wp_unslash( trim( $_REQUEST['status'] ) ) : ''; + foreach ( $this->status_list as $status => $col ) { + if ( ( 1 === intval( $_site->{$status} ) ) && ( $site_status !== $status ) ) { + $site_states[ $col[0] ] = $col[1]; + } + } + + /** + * Filter the default site display states for items in the Sites list table. + * + * @since 5.3.0 + * + * @param array $site_states An array of site states. Default 'Main', + * 'Archived', 'Mature', 'Spam', 'Deleted'. + * @param WP_Site $site The current site object. + */ + $site_states = apply_filters( 'display_site_states', $site_states, $_site ); + + if ( ! empty( $site_states ) ) { + $state_count = count( $site_states ); + $i = 0; + echo ' — '; + foreach ( $site_states as $state ) { + ++$i; + ( $i == $state_count ) ? $sep = '' : $sep = ', '; + echo "{$state}{$sep}"; + } + } + } + + /** * Gets the name of the default primary column. * * @since 4.3.0 @@ -510,11 +665,12 @@ * @param object $blog Site being acted upon. * @param string $column_name Current column name. * @param string $primary Primary column name. - * @return string Row actions output. + * @return string Row actions output for sites in Multisite, or an empty string + * if the current column is not the primary column. */ protected function handle_row_actions( $blog, $column_name, $primary ) { if ( $primary !== $column_name ) { - return; + return ''; } $blogname = untrailingslashit( $blog['domain'] . $blog['path'] ); @@ -536,19 +692,19 @@ $actions['edit'] = '' . __( 'Edit' ) . ''; $actions['backend'] = "" . __( 'Dashboard' ) . ''; if ( get_network()->site_id != $blog['blog_id'] ) { - if ( $blog['deleted'] == '1' ) { + if ( '1' == $blog['deleted'] ) { $actions['activate'] = '' . __( 'Activate' ) . ''; } else { $actions['deactivate'] = '' . __( 'Deactivate' ) . ''; } - if ( $blog['archived'] == '1' ) { + if ( '1' == $blog['archived'] ) { $actions['unarchive'] = '' . __( 'Unarchive' ) . ''; } else { $actions['archive'] = '' . _x( 'Archive', 'verb; site' ) . ''; } - if ( $blog['spam'] == '1' ) { + if ( '1' == $blog['spam'] ) { $actions['unspam'] = '' . _x( 'Not Spam', 'site' ) . ''; } else { $actions['spam'] = '' . _x( 'Spam', 'site' ) . ''; @@ -577,6 +733,7 @@ * or subdirectory multisite installation. */ $actions = apply_filters( 'manage_sites_action_links', array_filter( $actions ), $blog['blog_id'], $blogname ); + return $this->row_actions( $actions ); } }