diff --git a/src/wp-admin/includes/class-wp-comments-list-table.php b/src/wp-admin/includes/class-wp-comments-list-table.php
index ae462dd0dbe8b..258b23906d1ea 100644
--- a/src/wp-admin/includes/class-wp-comments-list-table.php
+++ b/src/wp-admin/includes/class-wp-comments-list-table.php
@@ -293,12 +293,6 @@ protected function get_views() {
}
foreach ( $stati as $status => $label ) {
- $current_link_attributes = '';
-
- if ( $status === $comment_status ) {
- $current_link_attributes = ' class="current" aria-current="page"';
- }
-
if ( 'mine' === $status ) {
$current_user_id = get_current_user_id();
$num_comments->mine = get_comments(
@@ -329,14 +323,18 @@ protected function get_views() {
$link = add_query_arg( 's', esc_attr( wp_unslash( $_REQUEST['s'] ) ), $link );
*/
- $status_links[ $status ] = "" . sprintf(
- translate_nooped_plural( $label, $num_comments->$status ),
- sprintf(
- '%s',
- ( 'moderated' === $status ) ? 'pending' : $status,
- number_format_i18n( $num_comments->$status )
- )
- ) . '';
+ $status_links[ $status ] = array(
+ 'url' => esc_url( $link ),
+ 'label' => sprintf(
+ translate_nooped_plural( $label, $num_comments->$status ),
+ sprintf(
+ '%s',
+ ( 'moderated' === $status ) ? 'pending' : $status,
+ number_format_i18n( $num_comments->$status )
+ )
+ ),
+ 'current' => $status === $comment_status,
+ );
}
/**
@@ -348,7 +346,7 @@ protected function get_views() {
* @param string[] $status_links An associative array of fully-formed comment status links. Includes 'All', 'Mine',
* 'Pending', 'Approved', 'Spam', and 'Trash'.
*/
- return apply_filters( 'comment_status_links', $status_links );
+ return apply_filters( 'comment_status_links', $this->get_views_links( $status_links ) );
}
/**
diff --git a/src/wp-admin/includes/class-wp-list-table.php b/src/wp-admin/includes/class-wp-list-table.php
index 8df48e6a0cda8..43f2413390f9f 100644
--- a/src/wp-admin/includes/class-wp-list-table.php
+++ b/src/wp-admin/includes/class-wp-list-table.php
@@ -1512,6 +1512,78 @@ public function ajax_response() {
die( wp_json_encode( $response ) );
}
+ /**
+ * Generates views links.
+ *
+ * @since 6.1.0
+ *
+ * @param array $link_data {
+ * An array of link data.
+ *
+ * @type string $url The link URL.
+ * @type string $label The link label.
+ * @type bool $current Optional. Whether this is the currently selected view.
+ * }
+ * @return array An array of link markup. Keys match the $link_data input array.
+ */
+ protected function get_views_links( $link_data = array() ) {
+ if ( ! is_array( $link_data ) ) {
+ _doing_it_wrong(
+ __METHOD__,
+ sprintf(
+ /* translators: %s: The $link_data argument. */
+ __( 'The %s argument must be an array.' ),
+ '$link_data'
+ ),
+ '6.1.0'
+ );
+
+ return array( '' );
+ }
+
+ $views_links = array();
+ foreach ( $link_data as $view => $link ) {
+ if ( empty( $link['url'] ) || ! is_string( $link['url'] ) || '' === trim( $link['url'] ) ) {
+ _doing_it_wrong(
+ __METHOD__,
+ sprintf(
+ /* translators: %1$s: The argument name. %2$s: The view name. */
+ __( 'The %1$s argument must be a non-empty string for %2$s.' ),
+ 'url',
+ esc_html( $view )
+ ),
+ '6.1.0'
+ );
+
+ continue;
+ }
+
+ if ( empty( $link['label'] ) || ! is_string( $link['label'] ) || '' === trim( $link['label'] ) ) {
+ _doing_it_wrong(
+ __METHOD__,
+ sprintf(
+ /* translators: %1$s: The argument name. %2$s: The view name. */
+ __( 'The %1$s argument must be a non-empty string for %2$s.' ),
+ 'label',
+ esc_html( $view )
+ ),
+ '6.1.0'
+ );
+
+ continue;
+ }
+
+ $views_links[ $view ] = sprintf(
+ '%s',
+ esc_url( $link['url'] ),
+ isset( $link['current'] ) && true === $link['current'] ? ' class="current" aria-current="page"' : '',
+ $link['label']
+ );
+ }
+
+ return $views_links;
+ }
+
/**
* Sends required variables to JavaScript land.
*
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 2d014700bb1c8..d50b7f84b493a 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
@@ -262,23 +262,19 @@ protected function get_views() {
$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
+ $view_links[ $status ] = array(
+ 'url' => esc_url( $full_url ),
+ 'label' => $label,
+ 'current' => $requested_status === $status || ( '' === $requested_status && 'all' === $status ),
);
}
}
- return $view_links;
+ return $this->get_views_links( $view_links );
}
/**
diff --git a/src/wp-admin/includes/class-wp-ms-themes-list-table.php b/src/wp-admin/includes/class-wp-ms-themes-list-table.php
index e87da5ca7a80b..70073e81303f7 100644
--- a/src/wp-admin/includes/class-wp-ms-themes-list-table.php
+++ b/src/wp-admin/includes/class-wp-ms-themes-list-table.php
@@ -444,16 +444,15 @@ protected function get_views() {
}
if ( 'search' !== $type ) {
- $status_links[ $type ] = sprintf(
- "%s",
- esc_url( add_query_arg( 'theme_status', $type, $url ) ),
- ( $type === $status ) ? ' class="current" aria-current="page"' : '',
- sprintf( $text, number_format_i18n( $count ) )
+ $status_links[ $type ] = array(
+ 'url' => esc_url( add_query_arg( 'theme_status', $type, $url ) ),
+ 'label' => sprintf( $text, number_format_i18n( $count ) ),
+ 'current' => $type === $status,
);
}
}
- return $status_links;
+ return $this->get_views_links( $status_links );
}
/**
diff --git a/src/wp-admin/includes/class-wp-ms-users-list-table.php b/src/wp-admin/includes/class-wp-ms-users-list-table.php
index d2ba7c72b5123..857a4f05a776d 100644
--- a/src/wp-admin/includes/class-wp-ms-users-list-table.php
+++ b/src/wp-admin/includes/class-wp-ms-users-list-table.php
@@ -137,13 +137,10 @@ protected function get_views() {
$super_admins = get_super_admins();
$total_admins = count( $super_admins );
- $current_link_attributes = 'super' !== $role ? ' class="current" aria-current="page"' : '';
- $role_links = array();
- $role_links['all'] = sprintf(
- '%s',
- network_admin_url( 'users.php' ),
- $current_link_attributes,
- sprintf(
+ $role_links = array();
+ $role_links['all'] = array(
+ 'url' => network_admin_url( 'users.php' ),
+ 'label' => sprintf(
/* translators: Number of users. */
_nx(
'All (%s)',
@@ -152,14 +149,13 @@ protected function get_views() {
'users'
),
number_format_i18n( $total_users )
- )
+ ),
+ 'current' => 'super' !== $role,
);
- $current_link_attributes = 'super' === $role ? ' class="current" aria-current="page"' : '';
- $role_links['super'] = sprintf(
- '%s',
- network_admin_url( 'users.php?role=super' ),
- $current_link_attributes,
- sprintf(
+
+ $role_links['super'] = array(
+ 'url' => network_admin_url( 'users.php?role=super' ),
+ 'label' => sprintf(
/* translators: Number of users. */
_n(
'Super Admin (%s)',
@@ -167,10 +163,11 @@ protected function get_views() {
$total_admins
),
number_format_i18n( $total_admins )
- )
+ ),
+ 'current' => 'super' === $role,
);
- return $role_links;
+ return $this->get_views_links( $role_links );
}
/**
diff --git a/src/wp-admin/includes/class-wp-plugin-install-list-table.php b/src/wp-admin/includes/class-wp-plugin-install-list-table.php
index 3c8dc1d2bbbe1..c482c7fa998cd 100644
--- a/src/wp-admin/includes/class-wp-plugin-install-list-table.php
+++ b/src/wp-admin/includes/class-wp-plugin-install-list-table.php
@@ -310,14 +310,16 @@ protected function get_views() {
$display_tabs = array();
foreach ( (array) $tabs as $action => $text ) {
- $current_link_attributes = ( $action === $tab ) ? ' class="current" aria-current="page"' : '';
- $href = self_admin_url( 'plugin-install.php?tab=' . $action );
- $display_tabs[ 'plugin-install-' . $action ] = "$text";
+ $display_tabs[ 'plugin-install-' . $action ] = array(
+ 'url' => self_admin_url( 'plugin-install.php?tab=' . $action ),
+ 'label' => $text,
+ 'current' => $action === $tab,
+ );
}
// No longer a real tab.
unset( $display_tabs['plugin-install-upload'] );
- return $display_tabs;
+ return $this->get_views_links( $display_tabs );
}
/**
diff --git a/src/wp-admin/includes/class-wp-plugins-list-table.php b/src/wp-admin/includes/class-wp-plugins-list-table.php
index d5a4a93e3fd98..930c89f1ecfbe 100644
--- a/src/wp-admin/includes/class-wp-plugins-list-table.php
+++ b/src/wp-admin/includes/class-wp-plugins-list-table.php
@@ -576,16 +576,15 @@ protected function get_views() {
}
if ( 'search' !== $type ) {
- $status_links[ $type ] = sprintf(
- "%s",
- add_query_arg( 'plugin_status', $type, 'plugins.php' ),
- ( $type === $status ) ? ' class="current" aria-current="page"' : '',
- sprintf( $text, number_format_i18n( $count ) )
+ $status_links[ $type ] = array(
+ 'url' => add_query_arg( 'plugin_status', $type, 'plugins.php' ),
+ 'label' => sprintf( $text, number_format_i18n( $count ) ),
+ 'current' => $type === $status,
);
}
}
- return $status_links;
+ return $this->get_views_links( $status_links );
}
/**
diff --git a/src/wp-admin/includes/class-wp-posts-list-table.php b/src/wp-admin/includes/class-wp-posts-list-table.php
index 4e7dad18c738b..764b60f65a443 100644
--- a/src/wp-admin/includes/class-wp-posts-list-table.php
+++ b/src/wp-admin/includes/class-wp-posts-list-table.php
@@ -331,16 +331,16 @@ protected function get_views() {
number_format_i18n( $this->user_posts_count )
);
- $mine = $this->get_edit_link( $mine_args, $mine_inner_html, $class );
+ $mine = array(
+ 'url' => esc_url( add_query_arg( $mine_args, 'edit.php' ) ),
+ 'label' => $mine_inner_html,
+ 'current' => isset( $_GET['author'] ) && ( $current_user_id === (int) $_GET['author'] ),
+ );
$all_args['all_posts'] = 1;
$class = '';
}
- if ( empty( $class ) && ( $this->is_base_request() || isset( $_REQUEST['all_posts'] ) ) ) {
- $class = 'current';
- }
-
$all_inner_html = sprintf(
/* translators: %s: Number of posts. */
_nx(
@@ -352,7 +352,11 @@ protected function get_views() {
number_format_i18n( $total_posts )
);
- $status_links['all'] = $this->get_edit_link( $all_args, $all_inner_html, $class );
+ $status_links['all'] = array(
+ 'url' => esc_url( add_query_arg( $all_args, 'edit.php' ) ),
+ 'label' => $all_inner_html,
+ 'current' => empty( $class ) && ( $this->is_base_request() || isset( $_REQUEST['all_posts'] ) ),
+ );
if ( $mine ) {
$status_links['mine'] = $mine;
@@ -381,7 +385,11 @@ protected function get_views() {
number_format_i18n( $num_posts->$status_name )
);
- $status_links[ $status_name ] = $this->get_edit_link( $status_args, $status_label, $class );
+ $status_links[ $status_name ] = array(
+ 'url' => esc_url( add_query_arg( $status_args, 'edit.php' ) ),
+ 'label' => $status_label,
+ 'current' => isset( $_REQUEST['post_status'] ) && $status_name === $_REQUEST['post_status'],
+ );
}
if ( ! empty( $this->sticky_posts_count ) ) {
@@ -404,7 +412,11 @@ protected function get_views() {
);
$sticky_link = array(
- 'sticky' => $this->get_edit_link( $sticky_args, $sticky_inner_html, $class ),
+ 'sticky' => array(
+ 'url' => esc_url( add_query_arg( $sticky_args, 'edit.php' ) ),
+ 'label' => $sticky_inner_html,
+ 'current' => ! empty( $_REQUEST['show_sticky'] ),
+ ),
);
// Sticky comes after Publish, or if not listed, after All.
@@ -412,7 +424,7 @@ protected function get_views() {
$status_links = array_merge( array_slice( $status_links, 0, $split ), $sticky_link, array_slice( $status_links, $split ) );
}
- return $status_links;
+ return $this->get_views_links( $status_links );
}
/**
diff --git a/src/wp-admin/includes/class-wp-privacy-requests-table.php b/src/wp-admin/includes/class-wp-privacy-requests-table.php
index 05dbcbc03128f..3061b73375d88 100644
--- a/src/wp-admin/includes/class-wp-privacy-requests-table.php
+++ b/src/wp-admin/includes/class-wp-privacy-requests-table.php
@@ -153,8 +153,7 @@ protected function get_views() {
// Normalized admin URL.
$admin_url = $this->get_admin_url();
- $current_link_attributes = empty( $current_status ) ? ' class="current" aria-current="page"' : '';
- $status_label = sprintf(
+ $status_label = sprintf(
/* translators: %s: Number of requests. */
_nx(
'All (%s)',
@@ -165,11 +164,10 @@ protected function get_views() {
number_format_i18n( $total_requests )
);
- $views['all'] = sprintf(
- '%s',
- esc_url( $admin_url ),
- $current_link_attributes,
- $status_label
+ $views['all'] = array(
+ 'url' => esc_url( $admin_url ),
+ 'label' => $status_label,
+ 'current' => empty( $current_status ),
);
foreach ( $statuses as $status => $label ) {
@@ -178,8 +176,7 @@ protected function get_views() {
continue;
}
- $current_link_attributes = $status === $current_status ? ' class="current" aria-current="page"' : '';
- $total_status_requests = absint( $counts->{$status} );
+ $total_status_requests = absint( $counts->{$status} );
if ( ! $total_status_requests ) {
continue;
@@ -192,15 +189,14 @@ protected function get_views() {
$status_link = add_query_arg( 'filter-status', $status, $admin_url );
- $views[ $status ] = sprintf(
- '%s',
- esc_url( $status_link ),
- $current_link_attributes,
- $status_label
+ $views[ $status ] = array(
+ 'url' => esc_url( $status_link ),
+ 'label' => $status_label,
+ 'current' => $status === $current_status,
);
}
- return $views;
+ return $this->get_views_links( $views );
}
/**
diff --git a/src/wp-admin/includes/class-wp-theme-install-list-table.php b/src/wp-admin/includes/class-wp-theme-install-list-table.php
index 17f8f8598caea..a02767f2775db 100644
--- a/src/wp-admin/includes/class-wp-theme-install-list-table.php
+++ b/src/wp-admin/includes/class-wp-theme-install-list-table.php
@@ -186,12 +186,14 @@ protected function get_views() {
$display_tabs = array();
foreach ( (array) $tabs as $action => $text ) {
- $current_link_attributes = ( $action === $tab ) ? ' class="current" aria-current="page"' : '';
- $href = self_admin_url( 'theme-install.php?tab=' . $action );
- $display_tabs[ 'theme-install-' . $action ] = "$text";
+ $display_tabs[ 'theme-install-' . $action ] = array(
+ 'url' => self_admin_url( 'theme-install.php?tab=' . $action ),
+ 'label' => $text,
+ 'current' => $action === $tab,
+ );
}
- return $display_tabs;
+ return $this->get_views_links( $display_tabs );
}
/**
diff --git a/src/wp-admin/includes/class-wp-users-list-table.php b/src/wp-admin/includes/class-wp-users-list-table.php
index 19921ae5bcac2..381354b36a4b8 100644
--- a/src/wp-admin/includes/class-wp-users-list-table.php
+++ b/src/wp-admin/includes/class-wp-users-list-table.php
@@ -185,10 +185,9 @@ protected function get_views() {
$url = 'users.php';
}
- $role_links = array();
- $avail_roles = array();
- $all_text = __( 'All' );
- $current_link_attributes = empty( $role ) ? ' class="current" aria-current="page"' : '';
+ $role_links = array();
+ $avail_roles = array();
+ $all_text = __( 'All' );
if ( $count_users ) {
if ( $this->is_site_users ) {
@@ -215,19 +214,17 @@ protected function get_views() {
);
}
- $role_links['all'] = sprintf( '%s', $url, $current_link_attributes, $all_text );
+ $role_links['all'] = array(
+ 'url' => $url,
+ 'label' => $all_text,
+ 'current' => empty( $role ),
+ );
foreach ( $wp_roles->get_names() as $this_role => $name ) {
if ( $count_users && ! isset( $avail_roles[ $this_role ] ) ) {
continue;
}
- $current_link_attributes = '';
-
- if ( $this_role === $role ) {
- $current_link_attributes = ' class="current" aria-current="page"';
- }
-
$name = translate_user_role( $name );
if ( $count_users ) {
$name = sprintf(
@@ -238,17 +235,15 @@ protected function get_views() {
);
}
- $role_links[ $this_role ] = "$name";
+ $role_links[ $this_role ] = array(
+ 'url' => esc_url( add_query_arg( 'role', $this_role, $url ) ),
+ 'label' => $name,
+ 'current' => $this_role === $role,
+ );
}
if ( ! empty( $avail_roles['none'] ) ) {
- $current_link_attributes = '';
-
- if ( 'none' === $role ) {
- $current_link_attributes = ' class="current" aria-current="page"';
- }
-
$name = __( 'No role' );
$name = sprintf(
/* translators: 1: User role name, 2: Number of users. */
@@ -257,10 +252,14 @@ protected function get_views() {
number_format_i18n( $avail_roles['none'] )
);
- $role_links['none'] = "$name";
+ $role_links['none'] = array(
+ 'url' => esc_url( add_query_arg( 'role', 'none', $url ) ),
+ 'label' => $name,
+ 'current' => 'none' === $role,
+ );
}
- return $role_links;
+ return $this->get_views_links( $role_links );
}
/**
diff --git a/tests/phpunit/tests/admin/wpCommentsListTable.php b/tests/phpunit/tests/admin/wpCommentsListTable.php
index b05c5fa5f1970..20fcd836e2cac 100644
--- a/tests/phpunit/tests/admin/wpCommentsListTable.php
+++ b/tests/phpunit/tests/admin/wpCommentsListTable.php
@@ -195,4 +195,23 @@ public function test_sortable_columns_with_current_ordering() {
$this->assertStringContainsString( 'column-date sorted desc', $output, 'Mismatch of CSS classes for the comment date column.' );
}
+ /**
+ * @ticket 42066
+ *
+ * @covers WP_Comments_List_Table::get_views
+ */
+ public function test_get_views_should_return_views_by_default() {
+ $this->table->prepare_items();
+
+ $expected = array(
+ 'all' => 'All (0)',
+ 'mine' => 'Mine (0)',
+ 'moderated' => 'Pending (0)',
+ 'approved' => 'Approved (0)',
+ 'spam' => 'Spam (0)',
+ 'trash' => 'Trash (0)',
+ );
+ $this->assertSame( $expected, $this->table->get_views() );
+ }
+
}
diff --git a/tests/phpunit/tests/admin/wpListTable.php b/tests/phpunit/tests/admin/wpListTable.php
index c07d7579c8c45..c28113d99f133 100644
--- a/tests/phpunit/tests/admin/wpListTable.php
+++ b/tests/phpunit/tests/admin/wpListTable.php
@@ -7,6 +7,24 @@
*/
class Tests_Admin_WpListTable extends WP_UnitTestCase {
+ /**
+ * List table.
+ *
+ * @var WP_List_Table $list_table
+ */
+ protected static $list_table;
+
+ public static function set_up_before_class() {
+ global $hook_suffix;
+
+ parent::set_up_before_class();
+
+ require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
+
+ $hook_suffix = '_wp_tests';
+ self::$list_table = new WP_List_Table();
+ }
+
/**
* Tests that `WP_List_Table::get_column_info()` only adds the primary
* column header when necessary.
@@ -104,4 +122,226 @@ public function data_should_only_add_primary_column_when_needed() {
return $datasets;
}
+
+ /**
+ * Tests the "get_views_links()" method.
+ *
+ * @ticket 42066
+ *
+ * @covers WP_List_Table::get_views_links
+ *
+ * @dataProvider data_get_views_links
+ *
+ * @param array $link_data {
+ * An array of link data.
+ *
+ * @type string $url The link URL.
+ * @type string $label The link label.
+ * @type bool $current Optional. Whether this is the currently selected view.
+ * }
+ * @param array $expected
+ */
+ public function test_get_views_links( $link_data, $expected ) {
+ $get_views_links = new ReflectionMethod( self::$list_table, 'get_views_links' );
+ $get_views_links->setAccessible( true );
+
+ $actual = $get_views_links->invokeArgs( self::$list_table, array( $link_data ) );
+
+ $this->assertSameSetsWithIndex( $expected, $actual );
+ }
+
+ /**
+ * Data provider.
+ *
+ * @return array
+ */
+ public function data_get_views_links() {
+ return array(
+ 'one "current" link' => array(
+ 'link_data' => array(
+ 'all' => array(
+ 'url' => 'https://example.org/',
+ 'label' => 'All',
+ 'current' => true,
+ ),
+ 'activated' => array(
+ 'url' => add_query_arg( 'status', 'activated', 'https://example.org/' ),
+ 'label' => 'Activated',
+ 'current' => false,
+ ),
+ ),
+ 'expected' => array(
+ 'all' => 'All',
+ 'activated' => 'Activated',
+ ),
+ ),
+ 'two "current" links' => array(
+ 'link_data' => array(
+ 'all' => array(
+ 'url' => 'https://example.org/',
+ 'label' => 'All',
+ 'current' => true,
+ ),
+ 'activated' => array(
+ 'url' => add_query_arg( 'status', 'activated', 'https://example.org/' ),
+ 'label' => 'Activated',
+ 'current' => true,
+ ),
+ ),
+ 'expected' => array(
+ 'all' => 'All',
+ 'activated' => 'Activated',
+ ),
+ ),
+ 'one "current" link and one without "current" key' => array(
+ 'link_data' => array(
+ 'all' => array(
+ 'url' => 'https://example.org/',
+ 'label' => 'All',
+ 'current' => true,
+ ),
+ 'activated' => array(
+ 'url' => add_query_arg( 'status', 'activated', 'https://example.org/' ),
+ 'label' => 'Activated',
+ ),
+ ),
+ 'expected' => array(
+ 'all' => 'All',
+ 'activated' => 'Activated',
+ ),
+ ),
+ 'one "current" link with escapable characters' => array(
+ 'link_data' => array(
+ 'all' => array(
+ 'url' => 'https://example.org/',
+ 'label' => 'All',
+ 'current' => true,
+ ),
+ 'activated' => array(
+ 'url' => add_query_arg(
+ array(
+ 'status' => 'activated',
+ 'sort' => 'desc',
+ ),
+ 'https://example.org/'
+ ),
+ 'label' => 'Activated',
+ 'current' => false,
+ ),
+ ),
+ 'expected' => array(
+ 'all' => 'All',
+ 'activated' => 'Activated',
+ ),
+ ),
+ );
+ }
+
+ /**
+ * Tests that "get_views_links()" throws a _doing_it_wrong().
+ *
+ * @ticket 42066
+ *
+ * @covers WP_List_Table::get_views_links
+ *
+ * @expectedIncorrectUsage WP_List_Table::get_views_links
+ *
+ * @dataProvider data_get_views_links_doing_it_wrong
+ *
+ * @param array $link_data {
+ * An array of link data.
+ *
+ * @type string $url The link URL.
+ * @type string $label The link label.
+ * @type bool $current Optional. Whether this is the currently selected view.
+ * }
+ */
+ public function test_get_views_links_doing_it_wrong( $link_data ) {
+ $get_views_links = new ReflectionMethod( self::$list_table, 'get_views_links' );
+ $get_views_links->setAccessible( true );
+ $get_views_links->invokeArgs( self::$list_table, array( $link_data ) );
+ }
+
+ /**
+ * Data provider.
+ *
+ * @return array
+ */
+ public function data_get_views_links_doing_it_wrong() {
+ return array(
+ 'non-array $link_data' => array(
+ 'link_data' => 'https://example.org, All, class="current" aria-current="page"',
+ ),
+ 'a link with no URL' => array(
+ 'link_data' => array(
+ 'all' => array(
+ 'label' => 'All',
+ 'current' => true,
+ ),
+ ),
+ ),
+ 'a link with an empty URL' => array(
+ 'link_data' => array(
+ 'all' => array(
+ 'url' => '',
+ 'label' => 'All',
+ 'current' => true,
+ ),
+ ),
+ ),
+ 'a link with a URL of only spaces' => array(
+ 'link_data' => array(
+ 'all' => array(
+ 'url' => ' ',
+ 'label' => 'All',
+ 'current' => true,
+ ),
+ ),
+ ),
+ 'a link with a non-string URL' => array(
+ 'link_data' => array(
+ 'all' => array(
+ 'url' => array(),
+ 'label' => 'All',
+ 'current' => true,
+ ),
+ ),
+ ),
+ 'a link with no label' => array(
+ 'link_data' => array(
+ 'all' => array(
+ 'url' => 'https://example.org/',
+ 'current' => true,
+ ),
+ ),
+ ),
+ 'a link with an empty label' => array(
+ 'link_data' => array(
+ 'all' => array(
+ 'url' => 'https://example.org/',
+ 'label' => '',
+ 'current' => true,
+ ),
+ ),
+ ),
+ 'a link with a label of only spaces' => array(
+ 'link_data' => array(
+ 'all' => array(
+ 'url' => 'https://example.org/',
+ 'label' => ' ',
+ 'current' => true,
+ ),
+ ),
+ ),
+ 'a link with a non-string label' => array(
+ 'link_data' => array(
+ 'all' => array(
+ 'url' => 'https://example.org/',
+ 'label' => array(),
+ 'current' => true,
+ ),
+ ),
+ ),
+ );
+ }
}
diff --git a/tests/phpunit/tests/admin/wpPluginInstallListTable.php b/tests/phpunit/tests/admin/wpPluginInstallListTable.php
new file mode 100644
index 0000000000000..406c740a443f3
--- /dev/null
+++ b/tests/phpunit/tests/admin/wpPluginInstallListTable.php
@@ -0,0 +1,27 @@
+table = _get_list_table( 'WP_Plugin_Install_List_Table', array( 'screen' => 'plugin-install' ) );
+ }
+
+ /**
+ * @ticket 42066
+ *
+ * @covers WP_Plugin_Install_List_Table::get_views
+ */
+ public function test_get_views_should_return_no_views_by_default() {
+ $this->assertSame( array(), $this->table->get_views() );
+ }
+}
diff --git a/tests/phpunit/tests/admin/wpPluginsListTable.php b/tests/phpunit/tests/admin/wpPluginsListTable.php
new file mode 100644
index 0000000000000..f97059d4754d8
--- /dev/null
+++ b/tests/phpunit/tests/admin/wpPluginsListTable.php
@@ -0,0 +1,59 @@
+table = _get_list_table( 'WP_Plugins_List_Table', array( 'screen' => 'plugins' ) );
+ }
+
+ /**
+ * @ticket 42066
+ *
+ * @covers WP_Plugins_List_Table::get_views
+ */
+ public function test_get_views_should_return_views_by_default() {
+ global $totals;
+
+ $totals_backup = $totals;
+ $totals = array(
+ 'all' => 45,
+ 'active' => 1,
+ 'recently_activated' => 2,
+ 'inactive' => 3,
+ 'mustuse' => 4,
+ 'dropins' => 5,
+ 'paused' => 6,
+ 'upgrade' => 7,
+ 'auto-update-enabled' => 8,
+ 'auto-update-disabled' => 9,
+ );
+
+ $expected = array(
+ 'all' => 'All (45)',
+ 'active' => 'Active (1)',
+ 'recently_activated' => 'Recently Active (2)',
+ 'inactive' => 'Inactive (3)',
+ 'mustuse' => 'Must-Use (4)',
+ 'dropins' => 'Drop-ins (5)',
+ 'paused' => 'Paused (6)',
+ 'upgrade' => 'Update Available (7)',
+ 'auto-update-enabled' => 'Auto-updates Enabled (8)',
+ 'auto-update-disabled' => 'Auto-updates Disabled (9)',
+ );
+
+ $actual = $this->table->get_views();
+ $totals = $totals_backup;
+
+ $this->assertSame( $expected, $actual );
+ }
+}
diff --git a/tests/phpunit/tests/admin/wpPostCommentsListTable.php b/tests/phpunit/tests/admin/wpPostCommentsListTable.php
new file mode 100644
index 0000000000000..98cb834bff2d7
--- /dev/null
+++ b/tests/phpunit/tests/admin/wpPostCommentsListTable.php
@@ -0,0 +1,39 @@
+table = _get_list_table( 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-post-comments' ) );
+ }
+
+ /**
+ * @ticket 42066
+ *
+ * @covers WP_Post_Comments_List_Table::get_views
+ */
+ public function test_get_views_should_return_views_by_default() {
+ $this->table->prepare_items();
+
+ $expected = array(
+ 'all' => 'All (0)',
+ 'mine' => 'Mine (0)',
+ 'moderated' => 'Pending (0)',
+ 'approved' => 'Approved (0)',
+ 'spam' => 'Spam (0)',
+ 'trash' => 'Trash (0)',
+ );
+ $this->assertSame( $expected, $this->table->get_views() );
+ }
+
+}
diff --git a/tests/phpunit/tests/admin/wpPostsListTable.php b/tests/phpunit/tests/admin/wpPostsListTable.php
index 306fddb65d9fa..c209179870944 100644
--- a/tests/phpunit/tests/admin/wpPostsListTable.php
+++ b/tests/phpunit/tests/admin/wpPostsListTable.php
@@ -319,4 +319,26 @@ public function test_empty_trash_button_should_not_be_shown_if_there_are_no_post
$this->assertStringNotContainsString( 'id="delete_all"', $output );
}
+ /**
+ * @ticket 42066
+ *
+ * @covers WP_Posts_List_Table::get_views
+ */
+ public function test_get_views_should_return_views_by_default() {
+ global $avail_post_stati;
+
+ $avail_post_stati_backup = $avail_post_stati;
+ $avail_post_stati = get_available_post_statuses();
+
+ $actual = $this->table->get_views();
+ $avail_post_stati = $avail_post_stati_backup;
+
+ $expected = array(
+ 'all' => 'All (38)',
+ 'publish' => 'Published (38)',
+ );
+
+ $this->assertSame( $expected, $actual );
+ }
+
}
diff --git a/tests/phpunit/tests/admin/wpPrivacyRequestsTable.php b/tests/phpunit/tests/admin/wpPrivacyRequestsTable.php
index 34b0b251f29b7..7f555c4d250f4 100644
--- a/tests/phpunit/tests/admin/wpPrivacyRequestsTable.php
+++ b/tests/phpunit/tests/admin/wpPrivacyRequestsTable.php
@@ -198,4 +198,17 @@ public function data_test_columns_should_be_sortable() {
),
);
}
+
+ /**
+ * @ticket 42066
+ *
+ * @covers WP_Privacy_Requests_List_Table::get_views
+ */
+ public function test_get_views_should_return_views_by_default() {
+ $expected = array(
+ 'all' => 'All (0)',
+ );
+
+ $this->assertSame( $expected, $this->get_mocked_class_instance()->get_views() );
+ }
}
diff --git a/tests/phpunit/tests/admin/wpThemeInstallListTable.php b/tests/phpunit/tests/admin/wpThemeInstallListTable.php
new file mode 100644
index 0000000000000..2c1c157c0f00b
--- /dev/null
+++ b/tests/phpunit/tests/admin/wpThemeInstallListTable.php
@@ -0,0 +1,27 @@
+table = _get_list_table( 'WP_Theme_Install_List_Table', array( 'screen' => 'theme-install' ) );
+ }
+
+ /**
+ * @ticket 42066
+ *
+ * @covers WP_Theme_Install_List_Table::get_views
+ */
+ public function test_get_views_should_return_no_views_by_default() {
+ $this->assertSame( array(), $this->table->get_views() );
+ }
+}
diff --git a/tests/phpunit/tests/admin/wpUsersListTable.php b/tests/phpunit/tests/admin/wpUsersListTable.php
new file mode 100644
index 0000000000000..bdf765fbfe0fc
--- /dev/null
+++ b/tests/phpunit/tests/admin/wpUsersListTable.php
@@ -0,0 +1,32 @@
+table = _get_list_table( 'WP_Users_List_Table', array( 'screen' => 'users' ) );
+ }
+
+ /**
+ * @ticket 42066
+ *
+ * @covers WP_Users_List_Table::get_views
+ */
+ public function test_get_views_should_return_views_by_default() {
+ $expected = array(
+ 'all' => 'All (1)',
+ 'administrator' => 'Administrator (1)',
+ );
+
+ $this->assertSame( $expected, $this->table->get_views() );
+ }
+}
diff --git a/tests/phpunit/tests/multisite/wpMsSitesListTable.php b/tests/phpunit/tests/multisite/wpMsSitesListTable.php
index 8bccd34f07fe2..559f7412f4334 100644
--- a/tests/phpunit/tests/multisite/wpMsSitesListTable.php
+++ b/tests/phpunit/tests/multisite/wpMsSitesListTable.php
@@ -230,5 +230,17 @@ public function test_ms_sites_list_table_subdirectory_path_search_items_with_tra
$this->assertSameSets( $expected, $items );
}
+
+ /**
+ * @ticket 42066
+ */
+ public function test_get_views_should_return_views_by_default() {
+ $expected = array(
+ 'all' => 'All (14)',
+ 'public' => 'Public (14)',
+ );
+
+ $this->assertSame( $expected, $this->table->get_views() );
+ }
}
endif;
diff --git a/tests/phpunit/tests/multisite/wpMsThemesListTable.php b/tests/phpunit/tests/multisite/wpMsThemesListTable.php
new file mode 100644
index 0000000000000..b02df1a740ffc
--- /dev/null
+++ b/tests/phpunit/tests/multisite/wpMsThemesListTable.php
@@ -0,0 +1,125 @@
+table = _get_list_table( 'WP_MS_Themes_List_Table', array( 'screen' => 'ms-themes' ) );
+ }
+
+ public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
+ self::$site_ids = array(
+ 'wordpress.org/' => array(
+ 'domain' => 'wordpress.org',
+ 'path' => '/',
+ ),
+ 'wordpress.org/foo/' => array(
+ 'domain' => 'wordpress.org',
+ 'path' => '/foo/',
+ ),
+ 'wordpress.org/foo/bar/' => array(
+ 'domain' => 'wordpress.org',
+ 'path' => '/foo/bar/',
+ ),
+ 'wordpress.org/afoo/' => array(
+ 'domain' => 'wordpress.org',
+ 'path' => '/afoo/',
+ ),
+ 'make.wordpress.org/' => array(
+ 'domain' => 'make.wordpress.org',
+ 'path' => '/',
+ ),
+ 'make.wordpress.org/foo/' => array(
+ 'domain' => 'make.wordpress.org',
+ 'path' => '/foo/',
+ ),
+ 'www.w.org/' => array(
+ 'domain' => 'www.w.org',
+ 'path' => '/',
+ ),
+ 'www.w.org/foo/' => array(
+ 'domain' => 'www.w.org',
+ 'path' => '/foo/',
+ ),
+ 'www.w.org/foo/bar/' => array(
+ 'domain' => 'www.w.org',
+ 'path' => '/foo/bar/',
+ ),
+ 'test.example.org/' => array(
+ 'domain' => 'test.example.org',
+ 'path' => '/',
+ ),
+ 'test2.example.org/' => array(
+ 'domain' => 'test2.example.org',
+ 'path' => '/',
+ ),
+ 'test3.example.org/zig/' => array(
+ 'domain' => 'test3.example.org',
+ 'path' => '/zig/',
+ ),
+ 'atest.example.org/' => array(
+ 'domain' => 'atest.example.org',
+ 'path' => '/',
+ ),
+ );
+
+ foreach ( self::$site_ids as &$id ) {
+ $id = $factory->blog->create( $id );
+ }
+ unset( $id );
+ }
+
+ public static function wpTearDownAfterClass() {
+ foreach ( self::$site_ids as $site_id ) {
+ wp_delete_site( $site_id );
+ }
+ }
+
+ /**
+ * @ticket 42066
+ *
+ * @covers WP_MS_Themes_List_Table::get_views
+ */
+ public function test_get_views_should_return_views_by_default() {
+ global $totals;
+
+ $totals_backup = $totals;
+ $totals = array(
+ 'all' => 21,
+ 'enabled' => 1,
+ 'disabled' => 2,
+ 'upgrade' => 3,
+ 'broken' => 4,
+ 'auto-update-enabled' => 5,
+ 'auto-update-disabled' => 6,
+ );
+
+ $expected = array(
+ 'all' => 'All (21)',
+ 'enabled' => 'Enabled (1)',
+ 'disabled' => 'Disabled (2)',
+ 'upgrade' => 'Update Available (3)',
+ 'broken' => 'Broken (4)',
+ 'auto-update-enabled' => 'Auto-updates Enabled (5)',
+ 'auto-update-disabled' => 'Auto-updates Disabled (6)',
+ );
+
+ $actual = $this->table->get_views();
+ $totals = $totals_backup;
+
+ $this->assertSame( $expected, $actual );
+ }
+}
diff --git a/tests/phpunit/tests/multisite/wpMsUsersListTable.php b/tests/phpunit/tests/multisite/wpMsUsersListTable.php
new file mode 100644
index 0000000000000..be17e7ae36470
--- /dev/null
+++ b/tests/phpunit/tests/multisite/wpMsUsersListTable.php
@@ -0,0 +1,107 @@
+table = _get_list_table( 'WP_MS_Users_List_Table', array( 'screen' => 'ms-users' ) );
+ }
+
+ public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
+ self::$site_ids = array(
+ 'wordpress.org/' => array(
+ 'domain' => 'wordpress.org',
+ 'path' => '/',
+ ),
+ 'wordpress.org/foo/' => array(
+ 'domain' => 'wordpress.org',
+ 'path' => '/foo/',
+ ),
+ 'wordpress.org/foo/bar/' => array(
+ 'domain' => 'wordpress.org',
+ 'path' => '/foo/bar/',
+ ),
+ 'wordpress.org/afoo/' => array(
+ 'domain' => 'wordpress.org',
+ 'path' => '/afoo/',
+ ),
+ 'make.wordpress.org/' => array(
+ 'domain' => 'make.wordpress.org',
+ 'path' => '/',
+ ),
+ 'make.wordpress.org/foo/' => array(
+ 'domain' => 'make.wordpress.org',
+ 'path' => '/foo/',
+ ),
+ 'www.w.org/' => array(
+ 'domain' => 'www.w.org',
+ 'path' => '/',
+ ),
+ 'www.w.org/foo/' => array(
+ 'domain' => 'www.w.org',
+ 'path' => '/foo/',
+ ),
+ 'www.w.org/foo/bar/' => array(
+ 'domain' => 'www.w.org',
+ 'path' => '/foo/bar/',
+ ),
+ 'test.example.org/' => array(
+ 'domain' => 'test.example.org',
+ 'path' => '/',
+ ),
+ 'test2.example.org/' => array(
+ 'domain' => 'test2.example.org',
+ 'path' => '/',
+ ),
+ 'test3.example.org/zig/' => array(
+ 'domain' => 'test3.example.org',
+ 'path' => '/zig/',
+ ),
+ 'atest.example.org/' => array(
+ 'domain' => 'atest.example.org',
+ 'path' => '/',
+ ),
+ );
+
+ foreach ( self::$site_ids as &$id ) {
+ $id = $factory->blog->create( $id );
+ }
+ unset( $id );
+ }
+
+ public static function wpTearDownAfterClass() {
+ foreach ( self::$site_ids as $site_id ) {
+ wp_delete_site( $site_id );
+ }
+ }
+
+ /**
+ * @ticket 42066
+ *
+ * @covers WP_MS_Users_List_Table::get_views
+ */
+ public function test_get_views_should_return_views_by_default() {
+ $all = get_user_count();
+ $super = count( get_super_admins() );
+
+ $expected = array(
+ 'all' => 'All (' . $all . ')',
+ 'super' => 'Super Admin (' . $super . ')',
+ );
+
+ $this->assertSame( $expected, $this->table->get_views() );
+ }
+}