Privacy: Allow column sorting in the privacy request admin tables.
This allows users to sort the export and erase personal data request tables by “Requester” (`post_title`, or user email) and “Requested” (`post_date`, or when the request was created), which can be helpful when sites have many requests present. Props birgire, ianbelanger, pbiron, desrosj. Fixes #43405. git-svn-id: https://develop.svn.wordpress.org/trunk@44628 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
17e5f4ad0b
commit
06371823e3
@ -809,6 +809,7 @@ function _wp_personal_data_export_page() {
|
|||||||
array(
|
array(
|
||||||
'plural' => 'privacy_requests',
|
'plural' => 'privacy_requests',
|
||||||
'singular' => 'privacy_request',
|
'singular' => 'privacy_request',
|
||||||
|
'screen' => 'export_personal_data',
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$requests_table->process_bulk_action();
|
$requests_table->process_bulk_action();
|
||||||
@ -882,6 +883,7 @@ function _wp_personal_data_removal_page() {
|
|||||||
array(
|
array(
|
||||||
'plural' => 'privacy_requests',
|
'plural' => 'privacy_requests',
|
||||||
'singular' => 'privacy_request',
|
'singular' => 'privacy_request',
|
||||||
|
'screen' => 'remove_personal_data',
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1090,7 +1092,15 @@ abstract class WP_Privacy_Requests_Table extends WP_List_Table {
|
|||||||
* @return array Default sortable columns.
|
* @return array Default sortable columns.
|
||||||
*/
|
*/
|
||||||
protected function get_sortable_columns() {
|
protected function get_sortable_columns() {
|
||||||
return array();
|
// The initial sorting is by 'Requested' (post_date) and descending.
|
||||||
|
// With initial sorting, the first click on 'Requested' should be ascending.
|
||||||
|
// With 'Requester' sorting active, the next click on 'Requested' should be descending.
|
||||||
|
$desc_first = isset( $_GET['orderby'] );
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'email' => 'requester',
|
||||||
|
'created_timestamp' => array( 'requested', $desc_first ),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1235,18 +1245,11 @@ abstract class WP_Privacy_Requests_Table extends WP_List_Table {
|
|||||||
* Prepare items to output.
|
* Prepare items to output.
|
||||||
*
|
*
|
||||||
* @since 4.9.6
|
* @since 4.9.6
|
||||||
|
* @since 5.1.0 Added support for column sorting.
|
||||||
*/
|
*/
|
||||||
public function prepare_items() {
|
public function prepare_items() {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
$primary = $this->get_primary_column_name();
|
|
||||||
$this->_column_headers = array(
|
|
||||||
$this->get_columns(),
|
|
||||||
array(),
|
|
||||||
$this->get_sortable_columns(),
|
|
||||||
$primary,
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->items = array();
|
$this->items = array();
|
||||||
$posts_per_page = $this->get_items_per_page( $this->request_type . '_requests_per_page' );
|
$posts_per_page = $this->get_items_per_page( $this->request_type . '_requests_per_page' );
|
||||||
$args = array(
|
$args = array(
|
||||||
@ -1258,6 +1261,19 @@ abstract class WP_Privacy_Requests_Table extends WP_List_Table {
|
|||||||
's' => isset( $_REQUEST['s'] ) ? sanitize_text_field( $_REQUEST['s'] ) : '',
|
's' => isset( $_REQUEST['s'] ) ? sanitize_text_field( $_REQUEST['s'] ) : '',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$orderby_mapping = array(
|
||||||
|
'requester' => 'post_title',
|
||||||
|
'requested' => 'post_date',
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( isset( $_REQUEST['orderby'] ) && isset( $orderby_mapping[ $_REQUEST['orderby'] ] ) ) {
|
||||||
|
$args['orderby'] = $orderby_mapping[ $_REQUEST['orderby'] ];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isset( $_REQUEST['order'] ) && in_array( strtoupper( $_REQUEST['order'] ), array( 'ASC', 'DESC' ), true ) ) {
|
||||||
|
$args['order'] = strtoupper( $_REQUEST['order'] );
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['filter-status'] ) ) {
|
if ( ! empty( $_REQUEST['filter-status'] ) ) {
|
||||||
$filter_status = isset( $_REQUEST['filter-status'] ) ? sanitize_text_field( $_REQUEST['filter-status'] ) : '';
|
$filter_status = isset( $_REQUEST['filter-status'] ) ? sanitize_text_field( $_REQUEST['filter-status'] ) : '';
|
||||||
$args['post_status'] = $filter_status;
|
$args['post_status'] = $filter_status;
|
||||||
|
186
tests/phpunit/tests/admin/wpPrivacyRequestsTable.php
Normal file
186
tests/phpunit/tests/admin/wpPrivacyRequestsTable.php
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Test the `WP_Privacy_Requests_Table` class.
|
||||||
|
*
|
||||||
|
* @package WordPress\UnitTests
|
||||||
|
*
|
||||||
|
* @since 5.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests_Admin_WpPrivacyRequestsTable class.
|
||||||
|
*
|
||||||
|
* @group admin
|
||||||
|
* @group privacy
|
||||||
|
*
|
||||||
|
* @since 5.1.0
|
||||||
|
*/
|
||||||
|
class Tests_Admin_WpPrivacyRequestsTable extends WP_UnitTestCase {
|
||||||
|
/**
|
||||||
|
* Get instance for mocked class.
|
||||||
|
*
|
||||||
|
* @since 5.1.0
|
||||||
|
*
|
||||||
|
* @return PHPUnit_Framework_MockObject_MockObject|WP_Privacy_Requests_Table $instance Mocked class instance.
|
||||||
|
*/
|
||||||
|
public function get_mocked_class_instance() {
|
||||||
|
if ( version_compare( PHP_VERSION, '5.3', '<' ) ) {
|
||||||
|
$this->markTestSkipped( 'ReflectionMethod::setAccessible is only available in PHP 5.3+' );
|
||||||
|
}
|
||||||
|
|
||||||
|
$args = array(
|
||||||
|
'plural' => 'privacy_requests',
|
||||||
|
'singular' => 'privacy_request',
|
||||||
|
'screen' => 'export_personal_data',
|
||||||
|
);
|
||||||
|
|
||||||
|
$instance = $this
|
||||||
|
->getMockBuilder( 'WP_Privacy_Requests_Table' )
|
||||||
|
->setConstructorArgs( array( $args ) )
|
||||||
|
->getMockForAbstractClass();
|
||||||
|
|
||||||
|
$reflection = new ReflectionClass( $instance );
|
||||||
|
|
||||||
|
// Set the request type as 'export_personal_data'.
|
||||||
|
$reflection_property = $reflection->getProperty( 'request_type' );
|
||||||
|
$reflection_property->setAccessible( true );
|
||||||
|
$reflection_property->setValue( $instance, 'export_personal_data' );
|
||||||
|
|
||||||
|
// Set the post type as 'user_request'.
|
||||||
|
$reflection_property = $reflection->getProperty( 'post_type' );
|
||||||
|
$reflection_property->setAccessible( true );
|
||||||
|
$reflection_property->setValue( $instance, 'user_request' );
|
||||||
|
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test columns should be sortable.
|
||||||
|
*
|
||||||
|
* @since 5.1.0
|
||||||
|
*
|
||||||
|
* @param string|null $order Order.
|
||||||
|
* @param string|null $orderby Order by.
|
||||||
|
* @param string|null $search Search term.
|
||||||
|
* @param string $expected Expected in SQL query.
|
||||||
|
|
||||||
|
* @dataProvider data_test_columns_should_be_sortable
|
||||||
|
* @covers WP_Privacy_Requests_Table::prepare_items()
|
||||||
|
* @ticket 43960
|
||||||
|
*/
|
||||||
|
public function test_columns_should_be_sortable( $order, $orderby, $search, $expected ) {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$table = $this->get_mocked_class_instance();
|
||||||
|
$this->sql = '';
|
||||||
|
|
||||||
|
$_REQUEST['order'] = $order;
|
||||||
|
$_REQUEST['orderby'] = $orderby;
|
||||||
|
$_REQUEST['s'] = $search;
|
||||||
|
|
||||||
|
add_filter( 'posts_request', array( $this, 'filter_posts_request' ) );
|
||||||
|
$table->prepare_items();
|
||||||
|
remove_filter( 'posts_request', array( $this, 'filter_posts_request' ) );
|
||||||
|
|
||||||
|
unset( $_REQUEST['order'] );
|
||||||
|
unset( $_REQUEST['orderby'] );
|
||||||
|
unset( $_REQUEST['s'] );
|
||||||
|
|
||||||
|
$this->assertContains( "ORDER BY {$wpdb->posts}.{$expected}", $this->sql );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter to grab the complete SQL query.
|
||||||
|
*
|
||||||
|
* @since 5.1.0
|
||||||
|
*
|
||||||
|
* @param string $request The complete SQL query.
|
||||||
|
* @return string $request The complete SQL query.
|
||||||
|
*/
|
||||||
|
public function filter_posts_request( $request ) {
|
||||||
|
$this->sql = $request;
|
||||||
|
return $request;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for `test_columns_should_be_sortable()`.
|
||||||
|
*
|
||||||
|
* @since 5.1.0
|
||||||
|
*
|
||||||
|
* @return array {
|
||||||
|
* @type array {
|
||||||
|
* @type string|null Order.
|
||||||
|
* @type string|null Order by.
|
||||||
|
* @type string|null Search term.
|
||||||
|
* @type string Expected in SQL query.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
public function data_test_columns_should_be_sortable() {
|
||||||
|
return array(
|
||||||
|
// Default order (ID) DESC.
|
||||||
|
array(
|
||||||
|
'order' => null,
|
||||||
|
'orderby' => null,
|
||||||
|
's' => null,
|
||||||
|
'expected' => 'post_date DESC',
|
||||||
|
),
|
||||||
|
// Default order (ID) DESC.
|
||||||
|
array(
|
||||||
|
'order' => '',
|
||||||
|
'orderby' => '',
|
||||||
|
's' => '',
|
||||||
|
'expected' => 'post_date DESC',
|
||||||
|
),
|
||||||
|
// Order by requester (post_title) ASC.
|
||||||
|
array(
|
||||||
|
'order' => 'ASC',
|
||||||
|
'orderby' => 'requester',
|
||||||
|
's' => '',
|
||||||
|
'expected' => 'post_title ASC',
|
||||||
|
),
|
||||||
|
// Order by requester (post_title) DESC.
|
||||||
|
array(
|
||||||
|
'order' => 'DESC',
|
||||||
|
'orderby' => 'requester',
|
||||||
|
's' => null,
|
||||||
|
'expected' => 'post_title DESC',
|
||||||
|
),
|
||||||
|
// Order by requested (post_date) ASC.
|
||||||
|
array(
|
||||||
|
'order' => 'ASC',
|
||||||
|
'orderby' => 'requested',
|
||||||
|
's' => null,
|
||||||
|
'expected' => 'post_date ASC',
|
||||||
|
),
|
||||||
|
// Order by requested (post_date) DESC.
|
||||||
|
array(
|
||||||
|
'order' => 'DESC',
|
||||||
|
'orderby' => 'requested',
|
||||||
|
's' => null,
|
||||||
|
'expected' => 'post_date DESC',
|
||||||
|
),
|
||||||
|
// Search and order by relevance.
|
||||||
|
array(
|
||||||
|
'order' => null,
|
||||||
|
'orderby' => null,
|
||||||
|
's' => 'foo',
|
||||||
|
'expected' => 'post_title LIKE',
|
||||||
|
),
|
||||||
|
// Search and order by requester (post_title) ASC.
|
||||||
|
array(
|
||||||
|
'order' => 'ASC',
|
||||||
|
'orderby' => 'requester',
|
||||||
|
's' => 'foo',
|
||||||
|
'expected' => 'post_title ASC',
|
||||||
|
),
|
||||||
|
// Search and order by requested (post_date) ASC.
|
||||||
|
array(
|
||||||
|
'order' => 'ASC',
|
||||||
|
'orderby' => 'requested',
|
||||||
|
's' => 'foo',
|
||||||
|
'expected' => 'post_date ASC',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user