Refactor notes controller and add ordering params (https://github.com/woocommerce/woocommerce-admin/pull/1878)
* Separate notes controller request args and add collection params * Fix page param var * Fix collection params sanitization * Allow array of note types to be queried * Add order and orderby collection params to notes controller * Allow sorting by order and orderby params in notes data store * Make sure notes are ordered by date and unread matches inbox note types * Allow status or type params to use an array of items * Add tests for notes ordering * Remove unnecessary query arg assignment in the notes data store * Update get_notes_count to use array for status and type
This commit is contained in:
parent
5324f223b6
commit
9c3faea12f
|
@ -113,6 +113,8 @@ export default compose(
|
|||
page: 1,
|
||||
per_page: QUERY_DEFAULTS.pageSize,
|
||||
type: 'info,warning',
|
||||
orderby: 'date',
|
||||
order: 'desc',
|
||||
};
|
||||
|
||||
const notes = getNotes( inboxQuery );
|
||||
|
|
|
@ -11,6 +11,9 @@ export function getUnreadNotes( select ) {
|
|||
const notesQuery = {
|
||||
page: 1,
|
||||
per_page: 1,
|
||||
type: 'info,warning',
|
||||
orderby: 'date',
|
||||
order: 'desc',
|
||||
};
|
||||
|
||||
const latestNote = getNotes( notesQuery );
|
||||
|
|
|
@ -43,6 +43,7 @@ class WC_Admin_REST_Admin_Notes_Controller extends WC_REST_CRUD_Controller {
|
|||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_items' ),
|
||||
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||
'args' => $this->get_collection_params(),
|
||||
),
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
)
|
||||
|
@ -108,34 +109,9 @@ class WC_Admin_REST_Admin_Notes_Controller extends WC_REST_CRUD_Controller {
|
|||
* @return WP_REST_Response
|
||||
*/
|
||||
public function get_items( $request ) {
|
||||
$per_page = isset( $request['per_page'] ) ? intval( $request['per_page'] ) : 10;
|
||||
if ( $per_page <= 0 ) {
|
||||
$per_page = 10;
|
||||
}
|
||||
$query_args = $this->prepare_objects_query( $request );
|
||||
|
||||
$page = isset( $request['page'] ) ? intval( $request['page'] ) : 1;
|
||||
if ( $page <= 0 ) {
|
||||
$page = 1;
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'per_page' => $per_page,
|
||||
'page' => $page,
|
||||
);
|
||||
|
||||
$type = isset( $request['type'] ) ? $request['type'] : '';
|
||||
$type = sanitize_text_field( $type );
|
||||
if ( ! empty( $type ) ) {
|
||||
$args['type'] = $type;
|
||||
}
|
||||
|
||||
$status = isset( $request['status'] ) ? $request['status'] : '';
|
||||
$status = sanitize_text_field( $status );
|
||||
if ( ! empty( $status ) ) {
|
||||
$args['status'] = $status;
|
||||
}
|
||||
|
||||
$notes = WC_Admin_Notes::get_notes( 'edit', $args );
|
||||
$notes = WC_Admin_Notes::get_notes( 'edit', $query_args );
|
||||
|
||||
$data = array();
|
||||
foreach ( (array) $notes as $note_obj ) {
|
||||
|
@ -145,11 +121,44 @@ class WC_Admin_REST_Admin_Notes_Controller extends WC_REST_CRUD_Controller {
|
|||
}
|
||||
|
||||
$response = rest_ensure_response( $data );
|
||||
$response->header( 'X-WP-Total', WC_Admin_Notes::get_notes_count( $type, $status ) );
|
||||
$response->header( 'X-WP-Total', WC_Admin_Notes::get_notes_count( $query_args['type'], $query_args['status'] ) );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare objects query.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return array
|
||||
*/
|
||||
protected function prepare_objects_query( $request ) {
|
||||
$args = array();
|
||||
$args['order'] = $request['order'];
|
||||
$args['orderby'] = $request['orderby'];
|
||||
$args['per_page'] = $request['per_page'];
|
||||
$args['page'] = $request['page'];
|
||||
$args['type'] = isset( $request['type'] ) ? $request['type'] : array();
|
||||
$args['status'] = isset( $request['status'] ) ? $request['status'] : array();
|
||||
|
||||
if ( 'date' === $args['orderby'] ) {
|
||||
$args['orderby'] = 'date_created';
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the query arguments for a request.
|
||||
*
|
||||
* Enables adding extra arguments or setting defaults for a post
|
||||
* collection request.
|
||||
*
|
||||
* @param array $args Key value array of query var to query value.
|
||||
* @param WP_REST_Request $request The request used.
|
||||
*/
|
||||
$args = apply_filters( 'woocommerce_rest_admin_notes_object_query', $args, $request );
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a given request has permission to read a single note.
|
||||
*
|
||||
|
@ -300,20 +309,65 @@ class WC_Admin_REST_Admin_Notes_Controller extends WC_REST_CRUD_Controller {
|
|||
* @return array
|
||||
*/
|
||||
public function get_collection_params() {
|
||||
$params = array();
|
||||
$params['context'] = $this->get_context_param( array( 'default' => 'view' ) );
|
||||
$params['type'] = array(
|
||||
'description' => __( 'Type of note.', 'woocommerce-admin' ),
|
||||
$params = array();
|
||||
$params['context'] = $this->get_context_param( array( 'default' => 'view' ) );
|
||||
$params['order'] = array(
|
||||
'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ),
|
||||
'type' => 'string',
|
||||
'enum' => WC_Admin_Note::get_allowed_types(),
|
||||
'default' => 'desc',
|
||||
'enum' => array( 'asc', 'desc' ),
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
);
|
||||
$params['status'] = array(
|
||||
'description' => __( 'Status of note.', 'woocommerce-admin' ),
|
||||
$params['orderby'] = array(
|
||||
'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ),
|
||||
'type' => 'string',
|
||||
'enum' => WC_Admin_Note::get_allowed_statuses(),
|
||||
'default' => 'date',
|
||||
'enum' => array(
|
||||
'note_id',
|
||||
'date',
|
||||
'type',
|
||||
'title',
|
||||
'status',
|
||||
),
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
);
|
||||
$params['page'] = array(
|
||||
'description' => __( 'Current page of the collection.', 'woocommerce-admin' ),
|
||||
'type' => 'integer',
|
||||
'default' => 1,
|
||||
'sanitize_callback' => 'absint',
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
'minimum' => 1,
|
||||
);
|
||||
$params['per_page'] = array(
|
||||
'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ),
|
||||
'type' => 'integer',
|
||||
'default' => 10,
|
||||
'minimum' => 1,
|
||||
'maximum' => 100,
|
||||
'sanitize_callback' => 'absint',
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
);
|
||||
$params['type'] = array(
|
||||
'description' => __( 'Type of note.', 'woocommerce-admin' ),
|
||||
'type' => 'array',
|
||||
'sanitize_callback' => 'wp_parse_slug_list',
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
'items' => array(
|
||||
'enum' => WC_Admin_Note::get_allowed_types(),
|
||||
'type' => 'string',
|
||||
),
|
||||
);
|
||||
$params['status'] = array(
|
||||
'description' => __( 'Status of note.', 'woocommerce-admin' ),
|
||||
'type' => 'array',
|
||||
'sanitize_callback' => 'wp_parse_slug_list',
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
'items' => array(
|
||||
'enum' => WC_Admin_Note::get_allowed_statuses(),
|
||||
'type' => 'string',
|
||||
),
|
||||
);
|
||||
return $params;
|
||||
}
|
||||
|
||||
|
|
|
@ -250,24 +250,21 @@ class WC_Admin_Notes_Data_Store extends WC_Data_Store_WP implements WC_Object_Da
|
|||
public function get_notes( $args = array() ) {
|
||||
global $wpdb;
|
||||
|
||||
$per_page = isset( $args['per_page'] ) ? intval( $args['per_page'] ) : 10;
|
||||
if ( $per_page <= 0 ) {
|
||||
$per_page = 10;
|
||||
}
|
||||
|
||||
$page = isset( $args['page'] ) ? intval( $args['page'] ) : 1;
|
||||
if ( $page <= 0 ) {
|
||||
$page = 1;
|
||||
}
|
||||
|
||||
$offset = $per_page * ( $page - 1 );
|
||||
$defaults = array(
|
||||
'per_page' => get_option( 'posts_per_page' ),
|
||||
'page' => 1,
|
||||
'order' => 'DESC',
|
||||
'orderby' => 'date_created',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$offset = $args['per_page'] * ( $args['page'] - 1 );
|
||||
$where_clauses = $this->get_notes_where_clauses( $args );
|
||||
|
||||
$query = $wpdb->prepare(
|
||||
"SELECT note_id, title, content FROM {$wpdb->prefix}wc_admin_notes WHERE 1=1{$where_clauses} ORDER BY note_id DESC LIMIT %d, %d",
|
||||
"SELECT note_id, title, content FROM {$wpdb->prefix}wc_admin_notes WHERE 1=1{$where_clauses} ORDER BY {$args['orderby']} {$args['order']} LIMIT %d, %d",
|
||||
$offset,
|
||||
$per_page
|
||||
$args['per_page']
|
||||
); // WPCS: unprepared SQL ok.
|
||||
|
||||
return $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||
|
@ -280,7 +277,7 @@ class WC_Admin_Notes_Data_Store extends WC_Data_Store_WP implements WC_Object_Da
|
|||
* @param string $status Comma separated list of statuses.
|
||||
* @return array An array of objects containing a note id.
|
||||
*/
|
||||
public function get_notes_count( $type = '', $status = '' ) {
|
||||
public function get_notes_count( $type = array(), $status = array() ) {
|
||||
global $wpdb;
|
||||
|
||||
$where_clauses = $this->get_notes_where_clauses(
|
||||
|
@ -308,8 +305,7 @@ class WC_Admin_Notes_Data_Store extends WC_Data_Store_WP implements WC_Object_Da
|
|||
$allowed_types = WC_Admin_Note::get_allowed_types();
|
||||
$where_type_array = array();
|
||||
if ( isset( $args['type'] ) ) {
|
||||
$args_types = explode( ',', $args['type'] );
|
||||
foreach ( (array) $args_types as $args_type ) {
|
||||
foreach ( $args['type'] as $args_type ) {
|
||||
$args_type = trim( $args_type );
|
||||
if ( in_array( $args_type, $allowed_types, true ) ) {
|
||||
$where_type_array[] = "'" . esc_sql( $args_type ) . "'";
|
||||
|
@ -320,8 +316,7 @@ class WC_Admin_Notes_Data_Store extends WC_Data_Store_WP implements WC_Object_Da
|
|||
$allowed_statuses = WC_Admin_Note::get_allowed_statuses();
|
||||
$where_status_array = array();
|
||||
if ( isset( $args['status'] ) ) {
|
||||
$args_statuses = explode( ',', $args['status'] );
|
||||
foreach ( (array) $args_statuses as $args_status ) {
|
||||
foreach ( $args['status'] as $args_status ) {
|
||||
$args_status = trim( $args_status );
|
||||
if ( in_array( $args_status, $allowed_statuses, true ) ) {
|
||||
$where_status_array[] = "'" . esc_sql( $args_status ) . "'";
|
||||
|
|
|
@ -86,7 +86,7 @@ class WC_Admin_Notes {
|
|||
* @param string $status Comma separated list of statuses.
|
||||
* @return int
|
||||
*/
|
||||
public static function get_notes_count( $type = '', $status = '' ) {
|
||||
public static function get_notes_count( $type = array(), $status = array() ) {
|
||||
$data_store = WC_Data_Store::load( 'admin-note' );
|
||||
return $data_store->get_notes_count( $type, $status );
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ class WC_Admin_Notes {
|
|||
$data_store = WC_Data_Store::load( 'admin-note' );
|
||||
$raw_notes = $data_store->get_notes(
|
||||
array(
|
||||
'status' => WC_Admin_Note::E_WC_ADMIN_NOTE_SNOOZED,
|
||||
'status' => array( WC_Admin_Note::E_WC_ADMIN_NOTE_SNOOZED ),
|
||||
)
|
||||
);
|
||||
$now = new DateTime();
|
||||
|
|
|
@ -194,7 +194,7 @@ function wc_admin_print_script_settings() {
|
|||
'weekdaysShort' => array_values( $wp_locale->weekday_abbrev ),
|
||||
),
|
||||
'currentUserData' => $current_user_data,
|
||||
'alertCount' => WC_Admin_Notes::get_notes_count( 'error,update', 'unactioned' ),
|
||||
'alertCount' => WC_Admin_Notes::get_notes_count( array( 'error', 'update' ), array( 'unactioned' ) ),
|
||||
'reviewsEnabled' => get_option( 'woocommerce_enable_reviews' ),
|
||||
'manageStock' => get_option( 'woocommerce_manage_stock' ),
|
||||
'commentModeration' => get_option( 'comment_moderation' ),
|
||||
|
|
|
@ -228,6 +228,44 @@ class WC_Tests_API_Admin_Notes extends WC_REST_Unit_Test_Case {
|
|||
$this->assertEmpty( $notes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ordering of notes.
|
||||
*/
|
||||
public function test_order_notes() {
|
||||
wp_set_current_user( $this->user );
|
||||
|
||||
$request = new WP_REST_Request( 'GET', $this->endpoint );
|
||||
$request->set_query_params(
|
||||
array(
|
||||
'orderby' => 'title',
|
||||
'order' => 'asc',
|
||||
)
|
||||
);
|
||||
$response = $this->server->dispatch( $request );
|
||||
$notes = $response->get_data();
|
||||
|
||||
$this->assertEquals( 200, $response->get_status() );
|
||||
$this->assertEquals( 3, count( $notes ) );
|
||||
$this->assertEquals( $notes[0]['title'], 'PHPUNIT_TEST_NOTE_1_TITLE' );
|
||||
$this->assertEquals( $notes[1]['title'], 'PHPUNIT_TEST_NOTE_2_TITLE' );
|
||||
$this->assertEquals( $notes[2]['title'], 'PHPUNIT_TEST_NOTE_3_TITLE' );
|
||||
|
||||
$request = new WP_REST_Request( 'GET', $this->endpoint );
|
||||
$request->set_query_params(
|
||||
array(
|
||||
'orderby' => 'status',
|
||||
'order' => 'desc',
|
||||
)
|
||||
);
|
||||
$response = $this->server->dispatch( $request );
|
||||
$notes = $response->get_data();
|
||||
|
||||
$this->assertEquals( 3, count( $notes ) );
|
||||
$this->assertEquals( $notes[0]['status'], WC_Admin_Note::E_WC_ADMIN_NOTE_UNACTIONED );
|
||||
$this->assertEquals( $notes[1]['status'], WC_Admin_Note::E_WC_ADMIN_NOTE_SNOOZED );
|
||||
$this->assertEquals( $notes[2]['status'], WC_Admin_Note::E_WC_ADMIN_NOTE_ACTIONED );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting lots of notes without permission. It should fail.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue