Customers Report: support between args for dates

This commit is contained in:
Paul Sealock 2019-01-29 08:58:07 +13:00
parent 7592dae4bb
commit bca0785e64
5 changed files with 81 additions and 43 deletions

View File

@ -52,6 +52,8 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
$args['country'] = $request['country'];
$args['last_active_before'] = $request['last_active_before'];
$args['last_active_after'] = $request['last_active_after'];
$args['last_active_min'] = $request['last_active_min'];
$args['last_active_max'] = $request['last_active_max'];
$args['orders_count_min'] = $request['orders_count_min'];
$args['orders_count_max'] = $request['orders_count_max'];
$args['total_spend_min'] = $request['total_spend_min'];
@ -61,7 +63,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
$args['last_order_before'] = $request['last_order_before'];
$args['last_order_after'] = $request['last_order_after'];
$between_params = array( 'orders_count', 'total_spend', 'avg_order_value' );
$between_params = array( 'orders_count', 'total_spend', 'avg_order_value', 'last_active' );
$normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params );
$args = array_merge( $args, $normalized );
@ -296,14 +298,14 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
'sanitize_callback' => 'absint',
'validate_callback' => 'rest_validate_request_arg',
);
$params['order'] = array(
$params['order'] = array(
'description' => __( 'Order sort attribute ascending or descending.', 'wc-admin' ),
'type' => 'string',
'default' => 'desc',
'enum' => array( 'asc', 'desc' ),
'validate_callback' => 'rest_validate_request_arg',
);
$params['orderby'] = array(
$params['orderby'] = array(
'description' => __( 'Sort collection by object attribute.', 'wc-admin' ),
'type' => 'string',
'default' => 'date_registered',
@ -321,7 +323,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
),
'validate_callback' => 'rest_validate_request_arg',
);
$params['match'] = array(
$params['match'] = array(
'description' => __( 'Indicates whether all the conditions should be true for the resulting set, or if any one of them is sufficient. Match affects the following parameters: status_is, status_is_not, product_includes, product_excludes, coupon_includes, coupon_excludes, customer, categories', 'wc-admin' ),
'type' => 'string',
'default' => 'all',
@ -331,7 +333,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
),
'validate_callback' => 'rest_validate_request_arg',
);
$params['name'] = array(
$params['name'] = array(
'description' => __( 'Limit response to objects with a specfic customer name.', 'wc-admin' ),
'type' => 'string',
'validate_callback' => 'rest_validate_request_arg',
@ -363,34 +365,39 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
'format' => 'date-time',
'validate_callback' => 'rest_validate_request_arg',
);
$params['registered_before'] = array(
$params['last_active_between'] = array(
'description' => __( 'Limit response to objects last active between two given ISO8601 compliant datetime.', 'wc-admin' ),
'type' => 'array',
'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_date_arg' ),
);
$params['registered_before'] = array(
'description' => __( 'Limit response to objects registered before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ),
'type' => 'string',
'format' => 'date-time',
'validate_callback' => 'rest_validate_request_arg',
);
$params['registered_after'] = array(
$params['registered_after'] = array(
'description' => __( 'Limit response to objects registered after (or at) a given ISO8601 compliant datetime.', 'wc-admin' ),
'type' => 'string',
'format' => 'date-time',
'validate_callback' => 'rest_validate_request_arg',
);
$params['orders_count_min'] = array(
$params['orders_count_min'] = array(
'description' => __( 'Limit response to objects with an order count greater than or equal to given integer.', 'wc-admin' ),
'type' => 'integer',
'sanitize_callback' => 'absint',
'validate_callback' => 'rest_validate_request_arg',
);
$params['orders_count_max'] = array(
$params['orders_count_max'] = array(
'description' => __( 'Limit response to objects with an order count less than or equal to given integer.', 'wc-admin' ),
'type' => 'integer',
'sanitize_callback' => 'absint',
'validate_callback' => 'rest_validate_request_arg',
);
$params['orders_count_between'] = array(
$params['orders_count_between'] = array(
'description' => __( 'Limit response to objects with an order count between two given integers.', 'wc-admin' ),
'type' => 'array',
'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ),
'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_numeric_arg' ),
);
$params['total_spend_min'] = array(
'description' => __( 'Limit response to objects with a total order spend greater than or equal to given number.', 'wc-admin' ),
@ -405,7 +412,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
$params['total_spend_between'] = array(
'description' => __( 'Limit response to objects with a total order spend between two given numbers.', 'wc-admin' ),
'type' => 'array',
'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ),
'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_numeric_arg' ),
);
$params['avg_order_value_min'] = array(
'description' => __( 'Limit response to objects with an average order spend greater than or equal to given number.', 'wc-admin' ),
@ -420,7 +427,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
$params['avg_order_value_between'] = array(
'description' => __( 'Limit response to objects with an average order spend between two given numbers.', 'wc-admin' ),
'type' => 'array',
'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ),
'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_numeric_arg' ),
);
$params['last_order_before'] = array(
'description' => __( 'Limit response to objects with last order before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ),

View File

@ -119,7 +119,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C
public function get_item_schema() {
// TODO: should any of these be 'indicator's?
$totals = array(
'customers_count' => array(
'customers_count' => array(
'description' => __( 'Number of customers.', 'wc-admin' ),
'type' => 'integer',
'context' => array( 'view', 'edit' ),
@ -131,7 +131,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'avg_total_spend' => array(
'avg_total_spend' => array(
'description' => __( 'Average total spend per customer.', 'wc-admin' ),
'type' => 'number',
'context' => array( 'view', 'edit' ),
@ -234,7 +234,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C
'format' => 'date-time',
'validate_callback' => 'rest_validate_request_arg',
);
$params['match'] = array(
$params['match'] = array(
'description' => __( 'Indicates whether all the conditions should be true for the resulting set, or if any one of them is sufficient. Match affects the following parameters: status_is, status_is_not, product_includes, product_excludes, coupon_includes, coupon_excludes, customer, categories', 'wc-admin' ),
'type' => 'string',
'default' => 'all',
@ -244,7 +244,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C
),
'validate_callback' => 'rest_validate_request_arg',
);
$params['name'] = array(
$params['name'] = array(
'description' => __( 'Limit response to objects with a specfic customer name.', 'wc-admin' ),
'type' => 'string',
'validate_callback' => 'rest_validate_request_arg',
@ -276,34 +276,34 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C
'format' => 'date-time',
'validate_callback' => 'rest_validate_request_arg',
);
$params['registered_before'] = array(
$params['registered_before'] = array(
'description' => __( 'Limit response to objects registered before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ),
'type' => 'string',
'format' => 'date-time',
'validate_callback' => 'rest_validate_request_arg',
);
$params['registered_after'] = array(
$params['registered_after'] = array(
'description' => __( 'Limit response to objects registered after (or at) a given ISO8601 compliant datetime.', 'wc-admin' ),
'type' => 'string',
'format' => 'date-time',
'validate_callback' => 'rest_validate_request_arg',
);
$params['orders_count_min'] = array(
$params['orders_count_min'] = array(
'description' => __( 'Limit response to objects with an order count greater than or equal to given integer.', 'wc-admin' ),
'type' => 'integer',
'sanitize_callback' => 'absint',
'validate_callback' => 'rest_validate_request_arg',
);
$params['orders_count_max'] = array(
$params['orders_count_max'] = array(
'description' => __( 'Limit response to objects with an order count less than or equal to given integer.', 'wc-admin' ),
'type' => 'integer',
'sanitize_callback' => 'absint',
'validate_callback' => 'rest_validate_request_arg',
);
$params['orders_count_between'] = array(
$params['orders_count_between'] = array(
'description' => __( 'Limit response to objects with an order count between two given integers.', 'wc-admin' ),
'type' => 'array',
'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ),
'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_numeric_arg' ),
);
$params['total_spend_min'] = array(
'description' => __( 'Limit response to objects with a total order spend greater than or equal to given number.', 'wc-admin' ),
@ -318,7 +318,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C
$params['total_spend_between'] = array(
'description' => __( 'Limit response to objects with a total order spend between two given numbers.', 'wc-admin' ),
'type' => 'array',
'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ),
'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_numeric_arg' ),
);
$params['avg_order_value_min'] = array(
'description' => __( 'Limit response to objects with an average order spend greater than or equal to given number.', 'wc-admin' ),
@ -333,7 +333,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C
$params['avg_order_value_between'] = array(
'description' => __( 'Limit response to objects with an average order spend between two given numbers.', 'wc-admin' ),
'type' => 'array',
'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ),
'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_numeric_arg' ),
);
$params['last_order_before'] = array(
'description' => __( 'Limit response to objects with last order before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ),

View File

@ -538,7 +538,7 @@ class WC_Admin_Reports_Interval {
* @param string $param Parameter name.
* @return WP_Error|boolean
*/
public static function rest_validate_between_arg( $value, $request, $param ) {
public static function rest_validate_between_numeric_arg( $value, $request, $param ) {
if ( ! wp_is_numeric_array( $value ) ) {
return new WP_Error(
'rest_invalid_param',
@ -561,4 +561,35 @@ class WC_Admin_Reports_Interval {
return true;
}
/**
* Validate a "*_between" range argument (an array with 2 date items).
*
* @param mixed $value Parameter value.
* @param WP_REST_Request $request REST Request.
* @param string $param Parameter name.
* @return WP_Error|boolean
*/
public static function rest_validate_between_date_arg( $value, $request, $param ) {
if ( ! wp_is_numeric_array( $value ) ) {
return new WP_Error(
'rest_invalid_param',
/* translators: 1: parameter name */
sprintf( __( '%1$s is not a numerically indexed array.', 'wc-admin' ), $param )
);
}
// check for dates here.
if (
2 !== count( $value )
) {
return new WP_Error(
'rest_invalid_param',
/* translators: %s: parameter name */
sprintf( __( '%s must contain 2 dates.', 'wc-admin' ), $param )
);
}
return true;
}
}

View File

@ -25,11 +25,11 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store
* @var array
*/
protected $column_types = array(
'customer_id' => 'intval',
'user_id' => 'intval',
'orders_count' => 'intval',
'total_spend' => 'floatval',
'avg_order_value' => 'floatval',
'customer_id' => 'intval',
'user_id' => 'intval',
'orders_count' => 'intval',
'total_spend' => 'floatval',
'avg_order_value' => 'floatval',
);
/**
@ -60,7 +60,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store
global $wpdb;
// Initialize some report columns that need disambiguation.
$this->report_columns['customer_id'] = $wpdb->prefix . self::TABLE_NAME . '.customer_id';
$this->report_columns['customer_id'] = $wpdb->prefix . self::TABLE_NAME . '.customer_id';
$this->report_columns['date_last_order'] = "MAX( {$wpdb->prefix}wc_order_stats.date_created ) as date_last_order";
}
@ -274,7 +274,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store
}
if ( $where_clauses ) {
$preceding_match = empty( $sql_query_params['where_time_clause'] ) ? ' AND ' : " {$match_operator} ";
$preceding_match = empty( $sql_query_params['where_time_clause'] ) ? ' AND ' : " {$match_operator} ";
$sql_query_params['where_clause'] = $preceding_match . implode( " {$match_operator} ", $where_clauses );
}
@ -284,7 +284,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store
}
if ( $having_clauses ) {
$preceding_match = empty( $sql_query_params['having_clause'] ) ? ' AND ' : " {$match_operator} ";
$preceding_match = empty( $sql_query_params['having_clause'] ) ? ' AND ' : " {$match_operator} ";
$sql_query_params['having_clause'] .= $preceding_match . implode( " {$match_operator} ", $having_clauses );
}
@ -304,7 +304,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store
$order_stats_table_name = $wpdb->prefix . 'wc_order_stats';
// These defaults are only partially applied when used via REST API, as that has its own defaults.
$defaults = array(
$defaults = array(
'per_page' => get_option( 'posts_per_page' ),
'page' => 1,
'order' => 'DESC',
@ -442,7 +442,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store
* Retrieve a guest (no user_id) customer row by email.
*
* @param string $email Email address.
* @returns false|array Customer array if found, boolean false if not.
* @return false|array Customer array if found, boolean false if not.
*/
public function get_guest_by_email( $email ) {
global $wpdb;
@ -467,7 +467,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store
* Retrieve a registered customer row by user_id.
*
* @param string|int $user_id User ID.
* @returns false|array Customer array if found, boolean false if not.
* @return false|array Customer array if found, boolean false if not.
*/
public function get_customer_by_user_id( $user_id ) {
global $wpdb;
@ -492,7 +492,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store
* Retrieve a registered customer row id by user_id.
*
* @param string|int $user_id User ID.
* @returns false|int Customer ID if found, boolean false if not.
* @return false|int Customer ID if found, boolean false if not.
*/
public static function get_customer_id_by_user_id( $user_id ) {
global $wpdb;
@ -554,7 +554,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store
if ( $customer_id ) {
// Preserve customer_id for existing user_id.
$data['customer_id'] = $customer_id;
$format[] = '%d';
$format[] = '%d';
}
return $wpdb->replace( $wpdb->prefix . self::TABLE_NAME, $data, $format );

View File

@ -836,19 +836,19 @@ class WC_Tests_Reports_Interval_Stats extends WC_Unit_Test_Case {
/**
* Test function that validates *_between query parameters.
*/
public function test_rest_validate_between_arg() {
public function test_rest_validate_between_numeric_arg() {
$this->assertIsWPError(
WC_Admin_Reports_Interval::rest_validate_between_arg( 'not array', null, 'param' ),
WC_Admin_Reports_Interval::rest_validate_between_numeric_arg( 'not array', null, 'param' ),
'param is not a numerically indexed array.'
);
$this->assertIsWPError(
WC_Admin_Reports_Interval::rest_validate_between_arg( array( 1 ), null, 'param' ),
WC_Admin_Reports_Interval::rest_validate_between_numeric_arg( array( 1 ), null, 'param' ),
'param must contain 2 numbers.'
);
$this->assertTrue(
WC_Admin_Reports_Interval::rest_validate_between_arg( array( 1, 2 ), null, 'param' )
WC_Admin_Reports_Interval::rest_validate_between_numeric_arg( array( 1, 2 ), null, 'param' )
);
}
}