diff --git a/src/Controllers/Version4/AdminNotes.php b/src/Controllers/Version4/AdminNotes.php deleted file mode 100644 index 17eb739d614..00000000000 --- a/src/Controllers/Version4/AdminNotes.php +++ /dev/null @@ -1,485 +0,0 @@ -namespace, - '/' . $this->rest_base, - array( - array( - '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' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d-]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique ID for the resource.', 'woocommerce' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Get a single note. - * - * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error - */ - public function get_item( $request ) { - $note = \WC_Admin_Notes::get_note( $request->get_param( 'id' ) ); - - if ( ! $note ) { - return new \WP_Error( - 'woocommerce_admin_notes_invalid_id', - __( 'Sorry, there is no resouce with that ID.', 'woocommerce' ), - array( 'status' => 404 ) - ); - } - - if ( is_wp_error( $note ) ) { - return $note; - } - - $data = $note->get_data(); - $data = $this->prepare_item_for_response( $data, $request ); - $data = $this->prepare_response_for_collection( $data ); - - return rest_ensure_response( $data ); - } - - /** - * Get all notes. - * - * @param WP_REST_Request $request Request data. - * @return WP_REST_Response - */ - public function get_items( $request ) { - $query_args = $this->prepare_objects_query( $request ); - - $notes = \WC_Admin_Notes::get_notes( 'edit', $query_args ); - - $data = array(); - foreach ( (array) $notes as $note_obj ) { - $note = $this->prepare_item_for_response( $note_obj, $request ); - $note = $this->prepare_response_for_collection( $note ); - $data[] = $note; - } - - $response = rest_ensure_response( $data ); - $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. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check whether a given request has permission to read notes. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Update a single note. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error - */ - public function update_item( $request ) { - $note = \WC_Admin_Notes::get_note( $request->get_param( 'id' ) ); - - if ( ! $note ) { - return new \WP_Error( - 'woocommerce_admin_notes_invalid_id', - __( 'Sorry, there is no resouce with that ID.', 'woocommerce' ), - array( 'status' => 404 ) - ); - } - - $note_changed = false; - if ( ! is_null( $request->get_param( 'status' ) ) ) { - $note->set_status( $request->get_param( 'status' ) ); - $note_changed = true; - } - - if ( ! is_null( $request->get_param( 'date_reminder' ) ) ) { - $note->set_date_reminder( $request->get_param( 'date_reminder' ) ); - $note_changed = true; - } - - if ( $note_changed ) { - $note->save(); - } - return $this->get_item( $request ); - } - - /** - * Makes sure the current user has access to WRITE the settings APIs. - * - * @param WP_REST_Request $request Full data about the request. - * @return WP_Error|bool - */ - public function update_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Prepare a path or query for serialization to the client. - * - * @param string $query The query, path, or URL to transform. - * @return string A fully formed URL. - */ - public function prepare_query_for_response( $query ) { - if ( empty( $query ) ) { - return $query; - } - if ( 'https://' === substr( $query, 0, 8 ) ) { - return $query; - } - if ( 'http://' === substr( $query, 0, 7 ) ) { - return $query; - } - if ( '?' === substr( $query, 0, 1 ) ) { - return admin_url( 'admin.php' . $query ); - } - - return admin_url( $query ); - } - - /** - * Prepare a note object for serialization. - * - * @param array $data Note data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $data, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data['date_created_gmt'] = wc_rest_prepare_date_response( $data['date_created'] ); - $data['date_created'] = wc_rest_prepare_date_response( $data['date_created'], false ); - $data['date_reminder_gmt'] = wc_rest_prepare_date_response( $data['date_reminder'] ); - $data['date_reminder'] = wc_rest_prepare_date_response( $data['date_reminder'], false ); - $data['title'] = stripslashes( $data['title'] ); - $data['content'] = stripslashes( $data['content'] ); - $data['is_snoozable'] = (bool) $data['is_snoozable']; - foreach ( (array) $data['actions'] as $key => $value ) { - $data['actions'][ $key ]->label = stripslashes( $data['actions'][ $key ]->label ); - $data['actions'][ $key ]->url = $this->prepare_query_for_response( $data['actions'][ $key ]->query ); - $data['actions'][ $key ]->status = stripslashes( $data['actions'][ $key ]->status ); - } - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - $response->add_links( - array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $data['id'] ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), - ), - ) - ); - /** - * Filter a note returned from the API. - * - * Allows modification of the note data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param array $data The original note. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_admin_note', $response, $data, $request ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - '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' ), - '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' ), - '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' ), - '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' ), - '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; - } - - /** - * Get the note's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'note', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'ID of the note record.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Name of the note.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'The type of the note (e.g. error, warning, etc.).', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'locale' => array( - 'description' => __( 'Locale used for the note title and content.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'title' => array( - 'description' => __( 'Title of the note.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'content' => array( - 'description' => __( 'Content of the note.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'icon' => array( - 'description' => __( 'Icon (gridicon) for the note.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'content_data' => array( - 'description' => __( 'Content data for the note. JSON string. Available for re-localization.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'status' => array( - 'description' => __( 'The status of the note (e.g. unactioned, actioned).', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'source' => array( - 'description' => __( 'Source of the note.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( 'Date the note was created.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'Date the note was created (GMT).', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_reminder' => array( - 'description' => __( 'Date after which the user should be reminded of the note, if any.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_reminder_gmt' => array( - 'description' => __( 'Date after which the user should be reminded of the note, if any (GMT).', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'is_snoozable' => array( - 'description' => __( 'Whether or a user can request to be reminded about the note.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'actions' => array( - 'description' => __( 'An array of actions, if any, for the note.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/Leaderboards.php b/src/Controllers/Version4/Leaderboards.php deleted file mode 100644 index 255e1779418..00000000000 --- a/src/Controllers/Version4/Leaderboards.php +++ /dev/null @@ -1,545 +0,0 @@ -namespace, - '/' . $this->rest_base, - array( - array( - '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' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/allowed', - array( - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_allowed_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - ), - 'schema' => array( $this, 'get_public_allowed_item_schema' ), - ), - true - ); - } - - /** - * Get the data for the coupons leaderboard. - * - * @param int $per_page Number of rows. - * @param string $after Items after date. - * @param string $before Items before date. - * @param string $persisted_query URL query string. - */ - public function get_coupons_leaderboard( $per_page, $after, $before, $persisted_query ) { - $coupons_data_store = new \WC_Admin_Reports_Coupons_Data_Store(); - $coupons_data = $per_page > 0 ? $coupons_data_store->get_data( - array( - 'orderby' => 'orders_count', - 'order' => 'desc', - 'after' => $after, - 'before' => $before, - 'per_page' => $per_page, - 'extended_info' => true, - ) - )->data : array(); - - $rows = array(); - foreach ( $coupons_data as $coupon ) { - $url_query = wp_parse_args( - array( - 'filter' => 'single_coupon', - 'coupons' => $coupon['coupon_id'], - ), - $persisted_query - ); - $coupon_url = wc_admin_url( 'analytics/coupons', $url_query ); - $coupon_code = isset( $coupon['extended_info'] ) && isset( $coupon['extended_info']['code'] ) ? $coupon['extended_info']['code'] : ''; - $rows[] = array( - array( - 'display' => "{$coupon_code}", - 'value' => $coupon_code, - ), - array( - 'display' => wc_admin_number_format( $coupon['orders_count'] ), - 'value' => $coupon['orders_count'], - ), - array( - 'display' => wc_price( $coupon['amount'] ), - 'value' => $coupon['amount'], - ), - ); - } - - return array( - 'id' => 'coupons', - 'label' => __( 'Top Coupons - Number of Orders', 'woocommerce' ), - 'headers' => array( - array( - 'label' => __( 'Coupon Code', 'woocommerce' ), - ), - array( - 'label' => __( 'Orders', 'woocommerce' ), - ), - array( - 'label' => __( 'Amount Discounted', 'woocommerce' ), - ), - ), - 'rows' => $rows, - ); - } - - /** - * Get the data for the categories leaderboard. - * - * @param int $per_page Number of rows. - * @param string $after Items after date. - * @param string $before Items before date. - * @param string $persisted_query URL query string. - */ - public function get_categories_leaderboard( $per_page, $after, $before, $persisted_query ) { - $categories_data_store = new \WC_Admin_Reports_Categories_Data_Store(); - $categories_data = $per_page > 0 ? $categories_data_store->get_data( - array( - 'orderby' => 'items_sold', - 'order' => 'desc', - 'after' => $after, - 'before' => $before, - 'per_page' => $per_page, - 'extended_info' => true, - ) - )->data : array(); - - $rows = array(); - foreach ( $categories_data as $category ) { - $url_query = wp_parse_args( - array( - 'filter' => 'single_category', - 'categories' => $category['category_id'], - ), - $persisted_query - ); - $category_url = wc_admin_url( 'analytics/categories', $url_query ); - $category_name = isset( $category['extended_info'] ) && isset( $category['extended_info']['name'] ) ? $category['extended_info']['name'] : ''; - $rows[] = array( - array( - 'display' => "{$category_name}", - 'value' => $category_name, - ), - array( - 'display' => wc_admin_number_format( $category['items_sold'] ), - 'value' => $category['items_sold'], - ), - array( - 'display' => wc_price( $category['net_revenue'] ), - 'value' => $category['net_revenue'], - ), - ); - } - - return array( - 'id' => 'categories', - 'label' => __( 'Top Categories - Items Sold', 'woocommerce' ), - 'headers' => array( - array( - 'label' => __( 'Category', 'woocommerce' ), - ), - array( - 'label' => __( 'Items Sold', 'woocommerce' ), - ), - array( - 'label' => __( 'Net Revenue', 'woocommerce' ), - ), - ), - 'rows' => $rows, - ); - } - - /** - * Get the data for the customers leaderboard. - * - * @param int $per_page Number of rows. - * @param string $after Items after date. - * @param string $before Items before date. - * @param string $persisted_query URL query string. - */ - public function get_customers_leaderboard( $per_page, $after, $before, $persisted_query ) { - $customers_data_store = new \WC_Admin_Reports_Customers_Data_Store(); - $customers_data = $per_page > 0 ? $customers_data_store->get_data( - array( - 'orderby' => 'total_spend', - 'order' => 'desc', - 'order_after' => $after, - 'order_before' => $before, - 'per_page' => $per_page, - ) - )->data : array(); - - $rows = array(); - foreach ( $customers_data as $customer ) { - $url_query = wp_parse_args( - array( - 'filter' => 'single_customer', - 'customers' => $customer['id'], - ), - $persisted_query - ); - $customer_url = wc_admin_url( 'analytics/customers', $url_query ); - $rows[] = array( - array( - 'display' => "{$customer['name']}", - 'value' => $customer['name'], - ), - array( - 'display' => wc_admin_number_format( $customer['orders_count'] ), - 'value' => $customer['orders_count'], - ), - array( - 'display' => wc_price( $customer['total_spend'] ), - 'value' => $customer['total_spend'], - ), - ); - } - - return array( - 'id' => 'customers', - 'label' => __( 'Top Customers - Total Spend', 'woocommerce' ), - 'headers' => array( - array( - 'label' => __( 'Customer Name', 'woocommerce' ), - ), - array( - 'label' => __( 'Orders', 'woocommerce' ), - ), - array( - 'label' => __( 'Total Spend', 'woocommerce' ), - ), - ), - 'rows' => $rows, - ); - } - - /** - * Get the data for the products leaderboard. - * - * @param int $per_page Number of rows. - * @param string $after Items after date. - * @param string $before Items before date. - * @param string $persisted_query URL query string. - */ - public function get_products_leaderboard( $per_page, $after, $before, $persisted_query ) { - $products_data_store = new \WC_Admin_Reports_Products_Data_Store(); - $products_data = $per_page > 0 ? $products_data_store->get_data( - array( - 'orderby' => 'items_sold', - 'order' => 'desc', - 'after' => $after, - 'before' => $before, - 'per_page' => $per_page, - 'extended_info' => true, - ) - )->data : array(); - - $rows = array(); - foreach ( $products_data as $product ) { - $url_query = wp_parse_args( - array( - 'filter' => 'single_product', - 'products' => $product['product_id'], - ), - $persisted_query - ); - $product_url = wc_admin_url( 'analytics/products', $url_query ); - $product_name = isset( $product['extended_info'] ) && isset( $product['extended_info']['name'] ) ? $product['extended_info']['name'] : ''; - $rows[] = array( - array( - 'display' => "{$product_name}", - 'value' => $product_name, - ), - array( - 'display' => wc_admin_number_format( $product['items_sold'] ), - 'value' => $product['items_sold'], - ), - array( - 'display' => wc_price( $product['net_revenue'] ), - 'value' => $product['net_revenue'], - ), - ); - } - - return array( - 'id' => 'products', - 'label' => __( 'Top Products - Items Sold', 'woocommerce' ), - 'headers' => array( - array( - 'label' => __( 'Product', 'woocommerce' ), - ), - array( - 'label' => __( 'Items Sold', 'woocommerce' ), - ), - array( - 'label' => __( 'Net Revenue', 'woocommerce' ), - ), - ), - 'rows' => $rows, - ); - } - - /** - * Get an array of all leaderboards. - * - * @param int $per_page Number of rows. - * @param string $after Items after date. - * @param string $before Items before date. - * @param string $persisted_query URL query string. - * @return array - */ - public function get_leaderboards( $per_page, $after, $before, $persisted_query ) { - $leaderboards = array( - $this->get_customers_leaderboard( $per_page, $after, $before, $persisted_query ), - $this->get_coupons_leaderboard( $per_page, $after, $before, $persisted_query ), - $this->get_categories_leaderboard( $per_page, $after, $before, $persisted_query ), - $this->get_products_leaderboard( $per_page, $after, $before, $persisted_query ), - ); - - return apply_filters( 'woocommerce_leaderboards', $leaderboards, $per_page, $after, $before, $persisted_query ); - } - - /** - * Return all leaderboards. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response - */ - public function get_items( $request ) { - $persisted_query = json_decode( $request['persisted_query'], true ); - $leaderboards = $this->get_leaderboards( $request['per_page'], $request['after'], $request['before'], $persisted_query ); - $data = array(); - - if ( ! empty( $leaderboards ) ) { - foreach ( $leaderboards as $leaderboard ) { - $response = $this->prepare_item_for_response( $leaderboard, $request ); - $data[] = $this->prepare_response_for_collection( $response ); - } - } - - return rest_ensure_response( $data ); - } - - /** - * Returns a list of allowed leaderboards. - * - * @param \WP_REST_Request $request Request data. - * @return array|\WP_Error - */ - public function get_allowed_items( $request ) { - $leaderboards = $this->get_leaderboards( 0, null, null, null ); - - $data = array(); - foreach ( $leaderboards as $leaderboard ) { - $data[] = (object) array( - 'id' => $leaderboard['id'], - 'label' => $leaderboard['label'], - 'headers' => $leaderboard['headers'], - ); - } - - $objects = array(); - foreach ( $data as $item ) { - $prepared = $this->prepare_item_for_response( $item, $request ); - $objects[] = $this->prepare_response_for_collection( $prepared ); - } - - $response = rest_ensure_response( $objects ); - $response->header( 'X-WP-Total', count( $data ) ); - $response->header( 'X-WP-TotalPages', 1 ); - - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - - return $response; - } - - /** - * Prepare the data object for response. - * - * @param object $item Data object. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $item, $request ) { - $data = $this->add_additional_fields_to_object( $item, $request ); - $data = $this->filter_response_by_context( $data, 'view' ); - $response = rest_ensure_response( $data ); - - /** - * Filter the list returned from the API. - * - * @param \WP_REST_Response $response The response object. - * @param array $item The original item. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_leaderboard', $response, $item, $request ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 5, - 'minimum' => 1, - 'maximum' => 20, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['persisted_query'] = array( - 'description' => __( 'URL query to persist across links.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - return $params; - } - - /** - * Get the schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'leaderboard', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'type' => 'string', - 'description' => __( 'Leaderboard ID.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'label' => array( - 'type' => 'string', - 'description' => __( 'Displayed title for the leaderboard.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'headers' => array( - 'type' => 'array', - 'description' => __( 'Table headers.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'array', - 'properties' => array( - 'label' => array( - 'description' => __( 'Table column header.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'rows' => array( - 'type' => 'array', - 'description' => __( 'Table rows.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'array', - 'properties' => array( - 'display' => array( - 'description' => __( 'Table cell display.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Table cell value.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get schema for the list of allowed leaderboards. - * - * @return array $schema - */ - public function get_public_allowed_item_schema() { - $schema = $this->get_public_item_schema(); - unset( $schema['properties']['rows'] ); - return $schema; - } -} diff --git a/src/Controllers/Version4/Reports/Categories.php b/src/Controllers/Version4/Reports/Categories.php deleted file mode 100644 index 1c8a6d65572..00000000000 --- a/src/Controllers/Version4/Reports/Categories.php +++ /dev/null @@ -1,314 +0,0 @@ -prepare_reports_query( $request ); - $categories_query = new \WC_Admin_Reports_Categories_Query( $query_args ); - $report_data = $categories_query->get_data(); - - if ( is_wp_error( $report_data ) ) { - return $report_data; - } - - if ( ! isset( $report_data->data ) || ! isset( $report_data->page_no ) || ! isset( $report_data->pages ) ) { - return new \WP_Error( 'woocommerce_rest_reports_categories_invalid_response', __( 'Invalid response from data store.', 'woocommerce' ), array( 'status' => 500 ) ); - } - - $out_data = array(); - - foreach ( $report_data->data as $datum ) { - $item = $this->prepare_item_for_response( $datum, $request ); - $out_data[] = $this->prepare_response_for_collection( $item ); - } - - $response = rest_ensure_response( $out_data ); - $response->header( 'X-WP-Total', (int) $report_data->total ); - $response->header( 'X-WP-TotalPages', (int) $report_data->pages ); - - $page = $report_data->page_no; - $max_pages = $report_data->pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $data = $report; - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $report ) ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_categories', $response, $report, $request ); - } - - /** - * Prepare links for the request. - * - * @param WC_Admin_Reports_Query $object Object data. - * @return array - */ - protected function prepare_links( $object ) { - $links = array( - 'category' => array( - 'href' => rest_url( sprintf( '/%s/products/categories/%d', $this->namespace, $object['category_id'] ) ), - ), - ); - - return $links; - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_categories', - 'type' => 'object', - 'properties' => array( - 'category_id' => array( - 'description' => __( 'Category ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'items_sold' => array( - 'description' => __( 'Amount of items sold.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'net_revenue' => array( - 'description' => __( 'Gross revenue.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'orders_count' => array( - 'description' => __( 'Amount of orders.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'products_count' => array( - 'description' => __( 'Amount of products.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'extended_info' => array( - 'name' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Category name.', 'woocommerce' ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'category_id', - 'enum' => array( - 'category_id', - 'items_sold', - 'net_revenue', - 'orders_count', - 'products_count', - 'category', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['interval'] = array( - 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'week', - 'enum' => array( - 'hour', - 'day', - 'week', - 'month', - 'quarter', - 'year', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['status_is'] = array( - 'description' => __( 'Limit result set to items that have the specified order status.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_slug_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'enum' => $this->get_order_statuses(), - 'type' => 'string', - ), - ); - $params['status_is_not'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified order status.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_slug_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'enum' => $this->get_order_statuses(), - 'type' => 'string', - ), - ); - $params['categories'] = array( - 'description' => __( 'Limit result set to all items that have the specified term assigned in the categories taxonomy.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['extended_info'] = array( - 'description' => __( 'Add additional piece of info about each category to the report.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'sanitize_callback' => 'wc_string_to_bool', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } - -} diff --git a/src/Controllers/Version4/Reports/CouponStats.php b/src/Controllers/Version4/Reports/CouponStats.php deleted file mode 100644 index e837f249bc5..00000000000 --- a/src/Controllers/Version4/Reports/CouponStats.php +++ /dev/null @@ -1,346 +0,0 @@ -prepare_reports_query( $request ); - $coupons_query = new \WC_Admin_Reports_Coupons_Stats_Query( $query_args ); - try { - $report_data = $coupons_query->get_data(); - } catch ( \WC_Admin_Reports_Parameter_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - - $out_data = array( - 'totals' => get_object_vars( $report_data->totals ), - 'intervals' => array(), - ); - - foreach ( $report_data->intervals as $interval_data ) { - $item = $this->prepare_item_for_response( (object) $interval_data, $request ); - $out_data['intervals'][] = $this->prepare_response_for_collection( $item ); - } - - $response = rest_ensure_response( $out_data ); - $response->header( 'X-WP-Total', (int) $report_data->total ); - $response->header( 'X-WP-TotalPages', (int) $report_data->pages ); - - $page = $report_data->page_no; - $max_pages = $report_data->pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $data = get_object_vars( $report ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_coupons_stats', $response, $report, $request ); - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $data_values = array( - 'amount' => array( - 'description' => __( 'Net discount amount.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'indicator' => true, - 'format' => 'currency', - ), - 'coupons_count' => array( - 'description' => __( 'Amount of coupons.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'orders_count' => array( - 'description' => __( 'Amount of discounted orders.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'indicator' => true, - ), - ); - - $segments = array( - 'segments' => array( - 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'segment_id' => array( - 'description' => __( 'Segment identificator.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $data_values, - ), - ), - ), - ), - ); - - $totals = array_merge( $data_values, $segments ); - - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_coupons_stats', - 'type' => 'object', - 'properties' => array( - 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $totals, - ), - 'intervals' => array( - 'description' => __( 'Reports data grouped by intervals.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'interval' => array( - 'description' => __( 'Type of interval.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'enum' => array( 'day', 'week', 'month', 'year' ), - ), - 'date_start' => array( - 'description' => __( "The date the report start, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_start_gmt' => array( - 'description' => __( 'The date the report start, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_end' => array( - 'description' => __( "The date the report end, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_end_gmt' => array( - 'description' => __( 'The date the report end, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $totals, - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'amount', - 'coupons_count', - 'orders_count', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['interval'] = array( - 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'week', - 'enum' => array( - 'hour', - 'day', - 'week', - 'month', - 'quarter', - 'year', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['coupons'] = array( - 'description' => __( 'Limit result set to coupons assigned specific coupon IDs.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['segmentby'] = array( - 'description' => __( 'Segment the response by additional constraint.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array( - 'product', - 'variation', - 'category', - 'coupon', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/Coupons.php b/src/Controllers/Version4/Reports/Coupons.php deleted file mode 100644 index 959e6b3fc2b..00000000000 --- a/src/Controllers/Version4/Reports/Coupons.php +++ /dev/null @@ -1,284 +0,0 @@ -prepare_reports_query( $request ); - $coupons_query = new \WC_Admin_Reports_Coupons_Query( $query_args ); - $report_data = $coupons_query->get_data(); - - $data = array(); - - foreach ( $report_data->data as $coupons_data ) { - $item = $this->prepare_item_for_response( $coupons_data, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - $response = rest_ensure_response( $data ); - $response->header( 'X-WP-Total', (int) $report_data->total ); - $response->header( 'X-WP-TotalPages', (int) $report_data->pages ); - - $page = $report_data->page_no; - $max_pages = $report_data->pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $data = $report; - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $report ) ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_coupons', $response, $report, $request ); - } - - /** - * Prepare links for the request. - * - * @param WC_Reports_Query $object Object data. - * @return array - */ - protected function prepare_links( $object ) { - $links = array( - 'coupon' => array( - 'href' => rest_url( sprintf( '/%s/coupons/%d', $this->namespace, $object['coupon_id'] ) ), - ), - ); - - return $links; - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_coupons', - 'type' => 'object', - 'properties' => array( - 'coupon_id' => array( - 'description' => __( 'Coupon ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'amount' => array( - 'description' => __( 'Net discount amount.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'orders_count' => array( - 'description' => __( 'Amount of orders.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'extended_info' => array( - 'code' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Coupon code.', 'woocommerce' ), - ), - 'date_created' => array( - 'type' => 'date-time', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Coupon creation date.', 'woocommerce' ), - ), - 'date_created_gmt' => array( - 'type' => 'date-time', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Coupon creation date in GMT.', 'woocommerce' ), - ), - 'date_expires' => array( - 'type' => 'date-time', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Coupon expiration date.', 'woocommerce' ), - ), - 'date_expires_gmt' => array( - 'type' => 'date-time', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Coupon expiration date in GMT.', 'woocommerce' ), - ), - 'discount_type' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'enum' => array_keys( wc_get_coupon_types() ), - 'description' => __( 'Coupon discount type.', 'woocommerce' ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'coupon_id', - 'enum' => array( - 'coupon_id', - 'code', - 'amount', - 'orders_count', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['coupons'] = array( - 'description' => __( 'Limit result set to coupons assigned specific coupon IDs.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['extended_info'] = array( - 'description' => __( 'Add additional piece of info about each coupon to the report.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'sanitize_callback' => 'wc_string_to_bool', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/CustomerStats.php b/src/Controllers/Version4/Reports/CustomerStats.php deleted file mode 100644 index cb7af69549d..00000000000 --- a/src/Controllers/Version4/Reports/CustomerStats.php +++ /dev/null @@ -1,359 +0,0 @@ -prepare_reports_query( $request ); - $customers_query = new \WC_Admin_Reports_Customers_Stats_Query( $query_args ); - $report_data = $customers_query->get_data(); - $out_data = array( - 'totals' => $report_data, - ); - - return rest_ensure_response( $out_data ); - } - - /** - * Prepare a report object for serialization. - * - * @param Array $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $data = $report; - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_customers_stats', $response, $report, $request ); - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - // @todo Should any of these be 'indicator's? - $totals = array( - 'customers_count' => array( - 'description' => __( 'Number of customers.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'avg_orders_count' => array( - 'description' => __( 'Average number of orders.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'avg_total_spend' => array( - 'description' => __( 'Average total spend per customer.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'format' => 'currency', - ), - 'avg_avg_order_value' => array( - 'description' => __( 'Average AOV per customer.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'format' => 'currency', - ), - ); - - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_customers_stats', - 'type' => 'object', - 'properties' => array( - 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $totals, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['registered_before'] = array( - 'description' => __( 'Limit response to objects registered before (or at) a given ISO8601 compliant datetime.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['registered_after'] = array( - 'description' => __( 'Limit response to objects registered after (or at) a given ISO8601 compliant datetime.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $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', 'woocommerce' ), - 'type' => 'string', - 'default' => 'all', - 'enum' => array( - 'all', - 'any', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['search'] = array( - 'description' => __( 'Limit response to objects with a customer field containing the search term. Searches the field provided by `searchby`.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['searchby'] = array( - 'description' => 'Limit results with `search` and `searchby` to specific fields containing the search term.', - 'type' => 'string', - 'default' => 'name', - 'enum' => array( - 'name', - 'username', - 'email', - ), - ); - $params['name_includes'] = array( - 'description' => __( 'Limit response to objects with specfic names.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['name_excludes'] = array( - 'description' => __( 'Limit response to objects excluding specfic names.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['username_includes'] = array( - 'description' => __( 'Limit response to objects with specfic usernames.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['username_excludes'] = array( - 'description' => __( 'Limit response to objects excluding specfic usernames.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['email_includes'] = array( - 'description' => __( 'Limit response to objects including emails.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['email_excludes'] = array( - 'description' => __( 'Limit response to objects excluding emails.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['country_includes'] = array( - 'description' => __( 'Limit response to objects with specfic countries.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['country_excludes'] = array( - 'description' => __( 'Limit response to objects excluding specfic countries.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['last_active_before'] = array( - 'description' => __( 'Limit response to objects last active before (or at) a given ISO8601 compliant datetime.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['last_active_after'] = array( - 'description' => __( 'Limit response to objects last active after (or at) a given ISO8601 compliant datetime.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['last_active_between'] = array( - 'description' => __( 'Limit response to objects last active between two given ISO8601 compliant datetime.', 'woocommerce' ), - '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.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['registered_after'] = array( - 'description' => __( 'Limit response to objects registered after (or at) a given ISO8601 compliant datetime.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['registered_between'] = array( - 'description' => __( 'Limit response to objects last active between two given ISO8601 compliant datetime.', 'woocommerce' ), - 'type' => 'array', - 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_date_arg' ), - ); - $params['orders_count_min'] = array( - 'description' => __( 'Limit response to objects with an order count greater than or equal to given integer.', 'woocommerce' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orders_count_max'] = array( - 'description' => __( 'Limit response to objects with an order count less than or equal to given integer.', 'woocommerce' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orders_count_between'] = array( - 'description' => __( 'Limit response to objects with an order count between two given integers.', 'woocommerce' ), - 'type' => 'array', - '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.', 'woocommerce' ), - 'type' => 'number', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['total_spend_max'] = array( - 'description' => __( 'Limit response to objects with a total order spend less than or equal to given number.', 'woocommerce' ), - 'type' => 'number', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['total_spend_between'] = array( - 'description' => __( 'Limit response to objects with a total order spend between two given numbers.', 'woocommerce' ), - 'type' => 'array', - '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.', 'woocommerce' ), - 'type' => 'number', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['avg_order_value_max'] = array( - 'description' => __( 'Limit response to objects with an average order spend less than or equal to given number.', 'woocommerce' ), - 'type' => 'number', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['avg_order_value_between'] = array( - 'description' => __( 'Limit response to objects with an average order spend between two given numbers.', 'woocommerce' ), - 'type' => 'array', - '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.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['last_order_after'] = array( - 'description' => __( 'Limit response to objects with last order after (or at) a given ISO8601 compliant datetime.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['customers'] = array( - 'description' => __( 'Limit result to items with specified customer ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/Customers.php b/src/Controllers/Version4/Reports/Customers.php deleted file mode 100644 index 8d9dfd89248..00000000000 --- a/src/Controllers/Version4/Reports/Customers.php +++ /dev/null @@ -1,511 +0,0 @@ -prepare_reports_query( $request ); - $customers_query = new \WC_Admin_Reports_Customers_Query( $query_args ); - $report_data = $customers_query->get_data(); - - $data = array(); - - foreach ( $report_data->data as $customer_data ) { - $item = $this->prepare_item_for_response( $customer_data, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - $response = rest_ensure_response( $data ); - $response->header( 'X-WP-Total', (int) $report_data->total ); - $response->header( 'X-WP-TotalPages', (int) $report_data->pages ); - - $page = $report_data->page_no; - $max_pages = $report_data->pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param array $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $report, $request ); - $data['date_registered_gmt'] = wc_rest_prepare_date_response( $data['date_registered'] ); - $data['date_registered'] = wc_rest_prepare_date_response( $data['date_registered'], false ); - $data['date_last_active_gmt'] = wc_rest_prepare_date_response( $data['date_last_active'] ); - $data['date_last_active'] = wc_rest_prepare_date_response( $data['date_last_active'], false ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $report ) ); - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_customers', $response, $report, $request ); - } - - /** - * Prepare links for the request. - * - * @param array $object Object data. - * @return array - */ - protected function prepare_links( $object ) { - if ( empty( $object['user_id'] ) ) { - return array(); - } - - return array( - 'customer' => array( - 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $object['user_id'] ) ), - ), - ); - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_customers', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Customer ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'user_id' => array( - 'description' => __( 'User ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'username' => array( - 'description' => __( 'Username.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'country' => array( - 'description' => __( 'Country.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'city' => array( - 'description' => __( 'City.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_registered' => array( - 'description' => __( 'Date registered.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_registered_gmt' => array( - 'description' => __( 'Date registered GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_last_active' => array( - 'description' => __( 'Date last active.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_last_active_gmt' => array( - 'description' => __( 'Date last active GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'orders_count' => array( - 'description' => __( 'Order count.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_spend' => array( - 'description' => __( 'Total spend.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'avg_order_value' => array( - 'description' => __( 'Avg order value.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['registered_before'] = array( - 'description' => __( 'Limit response to objects registered before (or at) a given ISO8601 compliant datetime.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['registered_after'] = array( - 'description' => __( 'Limit response to objects registered after (or at) a given ISO8601 compliant datetime.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources with orders published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources with orders published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'date_registered', - 'enum' => array( - 'username', - 'name', - 'country', - 'city', - 'postcode', - 'date_registered', - 'date_last_active', - 'orders_count', - 'total_spend', - 'avg_order_value', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $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', 'woocommerce' ), - 'type' => 'string', - 'default' => 'all', - 'enum' => array( - 'all', - 'any', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['search'] = array( - 'description' => __( 'Limit response to objects with a customer field containing the search term. Searches the field provided by `searchby`.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['searchby'] = array( - 'description' => 'Limit results with `search` and `searchby` to specific fields containing the search term.', - 'type' => 'string', - 'default' => 'name', - 'enum' => array( - 'name', - 'username', - 'email', - ), - ); - $params['name_includes'] = array( - 'description' => __( 'Limit response to objects with specfic names.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['name_excludes'] = array( - 'description' => __( 'Limit response to objects excluding specfic names.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['username_includes'] = array( - 'description' => __( 'Limit response to objects with specfic usernames.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['username_excludes'] = array( - 'description' => __( 'Limit response to objects excluding specfic usernames.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['email_includes'] = array( - 'description' => __( 'Limit response to objects including emails.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['email_excludes'] = array( - 'description' => __( 'Limit response to objects excluding emails.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['country_includes'] = array( - 'description' => __( 'Limit response to objects with specfic countries.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['country_excludes'] = array( - 'description' => __( 'Limit response to objects excluding specfic countries.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['last_active_before'] = array( - 'description' => __( 'Limit response to objects last active before (or at) a given ISO8601 compliant datetime.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['last_active_after'] = array( - 'description' => __( 'Limit response to objects last active after (or at) a given ISO8601 compliant datetime.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['last_active_between'] = array( - 'description' => __( 'Limit response to objects last active between two given ISO8601 compliant datetime.', 'woocommerce' ), - '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.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['registered_after'] = array( - 'description' => __( 'Limit response to objects registered after (or at) a given ISO8601 compliant datetime.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['registered_between'] = array( - 'description' => __( 'Limit response to objects last active between two given ISO8601 compliant datetime.', 'woocommerce' ), - 'type' => 'array', - 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_date_arg' ), - ); - $params['orders_count_min'] = array( - 'description' => __( 'Limit response to objects with an order count greater than or equal to given integer.', 'woocommerce' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orders_count_max'] = array( - 'description' => __( 'Limit response to objects with an order count less than or equal to given integer.', 'woocommerce' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orders_count_between'] = array( - 'description' => __( 'Limit response to objects with an order count between two given integers.', 'woocommerce' ), - 'type' => 'array', - '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.', 'woocommerce' ), - 'type' => 'number', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['total_spend_max'] = array( - 'description' => __( 'Limit response to objects with a total order spend less than or equal to given number.', 'woocommerce' ), - 'type' => 'number', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['total_spend_between'] = array( - 'description' => __( 'Limit response to objects with a total order spend between two given numbers.', 'woocommerce' ), - 'type' => 'array', - '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.', 'woocommerce' ), - 'type' => 'number', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['avg_order_value_max'] = array( - 'description' => __( 'Limit response to objects with an average order spend less than or equal to given number.', 'woocommerce' ), - 'type' => 'number', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['avg_order_value_between'] = array( - 'description' => __( 'Limit response to objects with an average order spend between two given numbers.', 'woocommerce' ), - 'type' => 'array', - '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.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['last_order_after'] = array( - 'description' => __( 'Limit response to objects with last order after (or at) a given ISO8601 compliant datetime.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['customers'] = array( - 'description' => __( 'Limit result to items with specified customer ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/DownloadStats.php b/src/Controllers/Version4/Reports/DownloadStats.php deleted file mode 100644 index 6d660f7b8a7..00000000000 --- a/src/Controllers/Version4/Reports/DownloadStats.php +++ /dev/null @@ -1,366 +0,0 @@ -prepare_reports_query( $request ); - $downloads_query = new \WC_Admin_Reports_Downloads_Stats_Query( $query_args ); - $report_data = $downloads_query->get_data(); - - $out_data = array( - 'totals' => get_object_vars( $report_data->totals ), - 'intervals' => array(), - ); - - foreach ( $report_data->intervals as $interval_data ) { - $item = $this->prepare_item_for_response( $interval_data, $request ); - $out_data['intervals'][] = $this->prepare_response_for_collection( $item ); - } - - $response = rest_ensure_response( $out_data ); - $response->header( 'X-WP-Total', (int) $report_data->total ); - $response->header( 'X-WP-TotalPages', (int) $report_data->pages ); - - $page = $report_data->page_no; - $max_pages = $report_data->pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param Array $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $data = $report; - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_downloads_stats', $response, $report, $request ); - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $totals = array( - 'download_count' => array( - 'description' => __( 'Number of downloads.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'indicator' => true, - ), - ); - - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_orders_stats', - 'type' => 'object', - 'properties' => array( - 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $totals, - ), - 'intervals' => array( - 'description' => __( 'Reports data grouped by intervals.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'interval' => array( - 'description' => __( 'Type of interval.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'enum' => array( 'day', 'week', 'month', 'year' ), - ), - 'date_start' => array( - 'description' => __( "The date the report start, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_start_gmt' => array( - 'description' => __( 'The date the report start, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_end' => array( - 'description' => __( "The date the report end, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_end_gmt' => array( - 'description' => __( 'The date the report end, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $totals, - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'download_count', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['interval'] = array( - 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'week', - 'enum' => array( - 'hour', - 'day', - 'week', - 'month', - 'quarter', - 'year', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $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', 'woocommerce' ), - 'type' => 'string', - 'default' => 'all', - 'enum' => array( - 'all', - 'any', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['product_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified product(s) assigned.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'sanitize_callback' => 'wp_parse_id_list', - - ); - $params['product_excludes'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified product(s) assigned.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'sanitize_callback' => 'wp_parse_id_list', - ); - $params['order_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified order ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['order_excludes'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified order ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['customer_includes'] = array( - 'description' => __( 'Limit response to objects that have the specified customer ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['customer_excludes'] = array( - 'description' => __( 'Limit response to objects that don\'t have the specified customer ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['ip_address_includes'] = array( - 'description' => __( 'Limit response to objects that have a specified ip address.', 'woocommerce' ), - 'type' => 'array', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'string', - ), - ); - - $params['ip_address_excludes'] = array( - 'description' => __( 'Limit response to objects that don\'t have a specified ip address.', 'woocommerce' ), - 'type' => 'array', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'string', - ), - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/Downloads.php b/src/Controllers/Version4/Reports/Downloads.php deleted file mode 100644 index f4828e4d7b8..00000000000 --- a/src/Controllers/Version4/Reports/Downloads.php +++ /dev/null @@ -1,374 +0,0 @@ -get_collection_params() ); - foreach ( $registered as $param_name ) { - if ( isset( $request[ $param_name ] ) ) { - $args[ $param_name ] = $request[ $param_name ]; - } - } - - $reports = new \WC_Admin_Reports_Downloads_Query( $args ); - $downloads_data = $reports->get_data(); - - $data = array(); - - foreach ( $downloads_data->data as $download_data ) { - $item = $this->prepare_item_for_response( $download_data, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - $response = rest_ensure_response( $data ); - - $response->header( 'X-WP-Total', (int) $downloads_data->total ); - $response->header( 'X-WP-TotalPages', (int) $downloads_data->pages ); - - $page = $downloads_data->page_no; - $max_pages = $downloads_data->pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param Array $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $data = $report; - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $report ) ); - - $response->data['date'] = get_date_from_gmt( $data['date_gmt'], 'Y-m-d H:i:s' ); - - // Figure out file name. - // Matches https://github.com/woocommerce/woocommerce/blob/4be0018c092e617c5d2b8c46b800eb71ece9ddef/includes/class-wc-download-handler.php#L197. - $product_id = intval( $data['product_id'] ); - $_product = wc_get_product( $product_id ); - $file_path = $_product->get_file_download_path( $data['download_id'] ); - $filename = basename( $file_path ); - $response->data['file_name'] = apply_filters( 'woocommerce_file_download_filename', $filename, $product_id ); - $response->data['file_path'] = $file_path; - $customer = new \WC_Customer( $data['user_id'] ); - $response->data['username'] = $customer->get_username(); - $response->data['order_number'] = $this->get_order_number( $data['order_id'] ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_downloads', $response, $report, $request ); - } - - /** - * Prepare links for the request. - * - * @param Array $object Object data. - * @return array Links for the given post. - */ - protected function prepare_links( $object ) { - $links = array( - 'product' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, 'products', $object['product_id'] ) ), - 'embeddable' => true, - ), - ); - - return $links; - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_downloads', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'ID.', 'woocommerce' ), - ), - 'product_id' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product ID.', 'woocommerce' ), - ), - 'date' => array( - 'description' => __( "The date of the download, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_gmt' => array( - 'description' => __( 'The date of the download, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'download_id' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Download ID.', 'woocommerce' ), - ), - 'file_name' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'File name.', 'woocommerce' ), - ), - 'file_path' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'File URL.', 'woocommerce' ), - ), - 'product_id' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product ID.', 'woocommerce' ), - ), - 'order_id' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Order ID.', 'woocommerce' ), - ), - 'order_number' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Order Number.', 'woocommerce' ), - ), - 'user_id' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'User ID for the downloader.', 'woocommerce' ), - ), - 'username' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'User name of the downloader.', 'woocommerce' ), - ), - 'ip_address' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'IP address for the downloader.', 'woocommerce' ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'product', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $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: products, orders, username, ip_address.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'all', - 'enum' => array( - 'all', - 'any', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['product_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified product(s) assigned.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['product_excludes'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified product(s) assigned.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'validate_callback' => 'rest_validate_request_arg', - 'sanitize_callback' => 'wp_parse_id_list', - ); - $params['order_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified order ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['order_excludes'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified order ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['customer_includes'] = array( - 'description' => __( 'Limit response to objects that have the specified user ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['customer_excludes'] = array( - 'description' => __( 'Limit response to objects that don\'t have the specified user ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['ip_address_includes'] = array( - 'description' => __( 'Limit response to objects that have a specified ip address.', 'woocommerce' ), - 'type' => 'array', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'string', - ), - ); - - $params['ip_address_excludes'] = array( - 'description' => __( 'Limit response to objects that don\'t have a specified ip address.', 'woocommerce' ), - 'type' => 'array', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'string', - ), - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/Import.php b/src/Controllers/Version4/Reports/Import.php deleted file mode 100644 index ea7907617ae..00000000000 --- a/src/Controllers/Version4/Reports/Import.php +++ /dev/null @@ -1,310 +0,0 @@ -namespace, - '/' . $this->rest_base, - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'import_items' ), - 'permission_callback' => array( $this, 'import_permissions_check' ), - 'args' => $this->get_import_collection_params(), - ), - 'schema' => array( $this, 'get_import_public_schema' ), - ) - ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/cancel', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'cancel_import' ), - 'permission_callback' => array( $this, 'import_permissions_check' ), - ), - 'schema' => array( $this, 'get_import_public_schema' ), - ) - ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/delete', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'delete_imported_items' ), - 'permission_callback' => array( $this, 'import_permissions_check' ), - ), - 'schema' => array( $this, 'get_import_public_schema' ), - ) - ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/status', - array( - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_import_status' ), - 'permission_callback' => array( $this, 'import_permissions_check' ), - ), - 'schema' => array( $this, 'get_import_public_schema' ), - ) - ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/totals', - array( - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_import_totals' ), - 'permission_callback' => array( $this, 'import_permissions_check' ), - 'args' => $this->get_import_collection_params(), - ), - 'schema' => array( $this, 'get_import_public_schema' ), - ) - ); - } - - /** - * Makes sure the current user has access to WRITE the settings APIs. - * - * @param \WP_REST_Request $request Full data about the request. - * @return \WP_Error|bool - */ - public function import_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Import data based on user request params. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response - */ - public function import_items( $request ) { - $query_args = $this->prepare_objects_query( $request ); - $import = \WC_Admin_Reports_Sync::regenerate_report_data( $query_args['days'], $query_args['skip_existing'] ); - - if ( is_wp_error( $import ) ) { - $result = array( - 'status' => 'error', - 'message' => $import->get_error_message(), - ); - } else { - $result = array( - 'status' => 'success', - 'message' => $import, - ); - } - - $response = $this->prepare_item_for_response( $result, $request ); - $data = $this->prepare_response_for_collection( $response ); - - return rest_ensure_response( $data ); - } - - /** - * Prepare request object as query args. - * - * @param \WP_REST_Request $request Request data. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = array(); - $args['skip_existing'] = $request['skip_existing']; - $args['days'] = $request['days']; - - return $args; - } - - /** - * Prepare the data object for response. - * - * @param object $item Data object. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $item, $request ) { - $data = $this->add_additional_fields_to_object( $item, $request ); - $data = $this->filter_response_by_context( $data, 'view' ); - $response = rest_ensure_response( $data ); - - /** - * Filter the list returned from the API. - * - * @param \WP_REST_Response $response The response object. - * @param array $item The original item. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_reports_import', $response, $item, $request ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_import_collection_params() { - $params = array(); - $params['days'] = array( - 'description' => __( 'Number of days to import.', 'woocommerce' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - 'minimum' => 1, - ); - $params['skip_existing'] = array( - 'description' => __( 'Skip importing existing order data.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'sanitize_callback' => 'wc_string_to_bool', - 'validate_callback' => 'rest_validate_request_arg', - ); - return $params; - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_import_public_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_import', - 'type' => 'object', - 'properties' => array( - 'status' => array( - 'description' => __( 'Regeneration status.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'message' => array( - 'description' => __( 'Regenerate data message.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Cancel all queued import actions. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response - */ - public function cancel_import( $request ) { - \WC_Admin_Reports_Sync::clear_queued_actions(); - - $result = array( - 'status' => 'success', - 'message' => __( 'All pending and in-progress import actions have been cancelled.', 'woocommerce' ), - ); - - $response = $this->prepare_item_for_response( $result, $request ); - $data = $this->prepare_response_for_collection( $response ); - - return rest_ensure_response( $data ); - } - - /** - * Delete all imported items. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response - */ - public function delete_imported_items( $request ) { - $delete = \WC_Admin_Reports_Sync::delete_report_data(); - - if ( is_wp_error( $delete ) ) { - $result = array( - 'status' => 'error', - 'message' => $delete->get_error_message(), - ); - } else { - $result = array( - 'status' => 'success', - 'message' => $delete, - ); - } - - $response = $this->prepare_item_for_response( $result, $request ); - $data = $this->prepare_response_for_collection( $response ); - - return rest_ensure_response( $data ); - } - - /** - * Get the status of the current import. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response - */ - public function get_import_status( $request ) { - $result = array( - 'is_importing' => \WC_Admin_Reports_Sync::is_importing(), - 'customers_total' => get_option( 'wc_admin_import_customers_total', 0 ), - 'customers_count' => get_option( 'wc_admin_import_customers_count', 0 ), - 'orders_total' => get_option( 'wc_admin_import_orders_total', 0 ), - 'orders_count' => get_option( 'wc_admin_import_orders_count', 0 ), - 'imported_from' => get_option( 'wc_admin_imported_from_date', false ), - ); - - $response = $this->prepare_item_for_response( $result, $request ); - $data = $this->prepare_response_for_collection( $response ); - - return rest_ensure_response( $data ); - } - - /** - * Get the total orders and customers based on user supplied params. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response - */ - public function get_import_totals( $request ) { - $query_args = $this->prepare_objects_query( $request ); - $totals = \WC_Admin_Reports_Sync::get_import_totals( $query_args['days'], $query_args['skip_existing'] ); - - $response = $this->prepare_item_for_response( $totals, $request ); - $data = $this->prepare_response_for_collection( $response ); - - return rest_ensure_response( $data ); - } -} diff --git a/src/Controllers/Version4/Reports/OrderStats.php b/src/Controllers/Version4/Reports/OrderStats.php deleted file mode 100644 index bc3d75b4d6d..00000000000 --- a/src/Controllers/Version4/Reports/OrderStats.php +++ /dev/null @@ -1,487 +0,0 @@ -prepare_reports_query( $request ); - $orders_query = new \WC_Admin_Reports_Orders_Stats_Query( $query_args ); - try { - $report_data = $orders_query->get_data(); - } catch ( \WC_Admin_Reports_Parameter_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - - $out_data = array( - 'totals' => get_object_vars( $report_data->totals ), - 'intervals' => array(), - ); - - foreach ( $report_data->intervals as $interval_data ) { - $item = $this->prepare_item_for_response( $interval_data, $request ); - $out_data['intervals'][] = $this->prepare_response_for_collection( $item ); - } - - $response = rest_ensure_response( $out_data ); - $response->header( 'X-WP-Total', (int) $report_data->total ); - $response->header( 'X-WP-TotalPages', (int) $report_data->pages ); - - $page = $report_data->page_no; - $max_pages = $report_data->pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param Array $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $data = $report; - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_orders_stats', $response, $report, $request ); - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $data_values = array( - 'net_revenue' => array( - 'description' => __( 'Net revenue.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'format' => 'currency', - ), - 'orders_count' => array( - 'description' => __( 'Amount of orders', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'indicator' => true, - ), - 'avg_order_value' => array( - 'description' => __( 'Average order value.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'indicator' => true, - 'format' => 'currency', - ), - 'avg_items_per_order' => array( - 'description' => __( 'Average items per order', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'num_items_sold' => array( - 'description' => __( 'Number of items sold', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'coupons' => array( - 'description' => __( 'Amount discounted by coupons.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'coupons_count' => array( - 'description' => __( 'Unique coupons count.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'num_returning_customers' => array( - 'description' => __( 'Number of orders done by returning customers', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'num_new_customers' => array( - 'description' => __( 'Number of orders done by new customers', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'products' => array( - 'description' => __( 'Number of distinct products sold.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ); - - $segments = array( - 'segments' => array( - 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'segment_id' => array( - 'description' => __( 'Segment identificator.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $data_values, - ), - ), - ), - ), - ); - - $totals = array_merge( $data_values, $segments ); - - // Products is not shown in intervals. - unset( $data_values['products'] ); - - $intervals = array_merge( $data_values, $segments ); - - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_orders_stats', - 'type' => 'object', - 'properties' => array( - 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $totals, - ), - 'intervals' => array( - 'description' => __( 'Reports data grouped by intervals.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'interval' => array( - 'description' => __( 'Type of interval.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'enum' => array( 'day', 'week', 'month', 'year' ), - ), - 'date_start' => array( - 'description' => __( "The date the report start, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_start_gmt' => array( - 'description' => __( 'The date the report start, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_end' => array( - 'description' => __( "The date the report end, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_end_gmt' => array( - 'description' => __( 'The date the report end, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $intervals, - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'net_revenue', - 'orders_count', - 'avg_order_value', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['interval'] = array( - 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'week', - 'enum' => array( - 'hour', - 'day', - 'week', - 'month', - 'quarter', - 'year', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $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', 'woocommerce' ), - 'type' => 'string', - 'default' => 'all', - 'enum' => array( - 'all', - 'any', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['status_is'] = array( - 'description' => __( 'Limit result set to items that have the specified order status.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_slug_list', - 'validate_callback' => 'rest_validate_request_arg', - 'default' => null, - 'items' => array( - 'enum' => $this->get_order_statuses(), - 'type' => 'string', - ), - ); - $params['status_is_not'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified order status.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_slug_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'enum' => $this->get_order_statuses(), - 'type' => 'string', - ), - ); - $params['product_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified product(s) assigned.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'sanitize_callback' => 'wp_parse_id_list', - - ); - $params['product_excludes'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified product(s) assigned.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'sanitize_callback' => 'wp_parse_id_list', - ); - $params['coupon_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified coupon(s) assigned.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'sanitize_callback' => 'wp_parse_id_list', - ); - $params['coupon_excludes'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified coupon(s) assigned.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'sanitize_callback' => 'wp_parse_id_list', - ); - $params['customer'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified coupon(s) assigned.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array( - 'new', - 'returning', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['refunds'] = array( - 'description' => __( 'Limit result set to specific types of refunds.', 'woocommerce' ), - 'type' => 'string', - 'default' => '', - 'enum' => array( - '', - 'all', - 'partial', - 'full', - 'none', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['segmentby'] = array( - 'description' => __( 'Segment the response by additional constraint.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array( - 'product', - 'category', - 'variation', - 'coupon', - 'customer_type', // new vs returning. - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } - -} diff --git a/src/Controllers/Version4/Reports/Orders.php b/src/Controllers/Version4/Reports/Orders.php deleted file mode 100644 index c4c71a12c9e..00000000000 --- a/src/Controllers/Version4/Reports/Orders.php +++ /dev/null @@ -1,371 +0,0 @@ -prepare_reports_query( $request ); - $orders_query = new \WC_Admin_Reports_Orders_Query( $query_args ); - $report_data = $orders_query->get_data(); - - $data = array(); - - foreach ( $report_data->data as $orders_data ) { - $orders_data['order_number'] = $this->get_order_number( $orders_data['order_id'] ); - $item = $this->prepare_item_for_response( $orders_data, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - $response = rest_ensure_response( $data ); - $response->header( 'X-WP-Total', (int) $report_data->total ); - $response->header( 'X-WP-TotalPages', (int) $report_data->pages ); - - $page = $report_data->page_no; - $max_pages = $report_data->pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $data = $report; - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $report ) ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_orders', $response, $report, $request ); - } - - /** - * Prepare links for the request. - * - * @param WC_Reports_Query $object Object data. - * @return array - */ - protected function prepare_links( $object ) { - $links = array( - 'order' => array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $object['order_id'] ) ), - ), - ); - - return $links; - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_orders', - 'type' => 'object', - 'properties' => array( - 'order_id' => array( - 'description' => __( 'Order ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'order_number' => array( - 'description' => __( 'Order Number.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( 'Date the order was created.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'status' => array( - 'description' => __( 'Order status.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'customer_id' => array( - 'description' => __( 'Customer ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'num_items_sold' => array( - 'description' => __( 'Number of items sold.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'net_total' => array( - 'description' => __( 'Net total revenue.', 'woocommerce' ), - 'type' => 'float', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'customer_type' => array( - 'description' => __( 'Returning or new customer.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'extended_info' => array( - 'products' => array( - 'type' => 'array', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'List of product IDs and names.', 'woocommerce' ), - ), - 'categories' => array( - 'type' => 'array', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Category IDs.', 'woocommerce' ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 0, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'num_items_sold', - 'net_total', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['product_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified product(s) assigned.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['product_excludes'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified product(s) assigned.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'validate_callback' => 'rest_validate_request_arg', - 'sanitize_callback' => 'wp_parse_id_list', - ); - $params['coupon_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified coupon(s) assigned.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['coupon_excludes'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified coupon(s) assigned.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'validate_callback' => 'rest_validate_request_arg', - 'sanitize_callback' => 'wp_parse_id_list', - ); - $params['status_is'] = array( - 'description' => __( 'Limit result set to items that have the specified order status.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_slug_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'enum' => $this->get_order_statuses(), - 'type' => 'string', - ), - ); - $params['status_is_not'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified order status.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_slug_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'enum' => $this->get_order_statuses(), - 'type' => 'string', - ), - ); - $params['customer_type'] = array( - 'description' => __( 'Limit result set to returning or new customers.', 'woocommerce' ), - 'type' => 'string', - 'default' => '', - 'enum' => array( - '', - 'returning', - 'new', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['refunds'] = array( - 'description' => __( 'Limit result set to specific types of refunds.', 'woocommerce' ), - 'type' => 'string', - 'default' => '', - 'enum' => array( - '', - 'all', - 'partial', - 'full', - 'none', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['extended_info'] = array( - 'description' => __( 'Add additional piece of info about each coupon to the report.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'sanitize_callback' => 'wc_string_to_bool', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/PerformanceIndicators.php b/src/Controllers/Version4/Reports/PerformanceIndicators.php deleted file mode 100644 index 164b34a2bec..00000000000 --- a/src/Controllers/Version4/Reports/PerformanceIndicators.php +++ /dev/null @@ -1,499 +0,0 @@ -namespace, - '/' . $this->rest_base, - array( - array( - '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' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/allowed', - array( - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_allowed_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - 'schema' => array( $this, 'get_public_allowed_item_schema' ), - ) - ); - } - - /** - * Maps query arguments from the REST request. - * - * @param array $request Request array. - * @return array - */ - protected function prepare_reports_query( $request ) { - $args = array(); - $args['before'] = $request['before']; - $args['after'] = $request['after']; - $args['stats'] = $request['stats']; - return $args; - } - - /** - * Get information such as allowed stats, stat labels, and endpoint data from stats reports. - * - * @return \WP_Error|True - */ - private function get_indicator_data() { - // Data already retrieved. - if ( ! empty( $this->endpoints ) && ! empty( $this->labels ) && ! empty( $this->allowed_stats ) ) { - return true; - } - - $request = new \WP_REST_Request( 'GET', '/wc/v4/reports' ); - $response = rest_do_request( $request ); - $endpoints = $response->get_data(); - $allowed_stats = array(); - if ( 200 !== $response->get_status() ) { - return new \WP_Error( 'woocommerce_reports_performance_indicators_result_failed', __( 'Sorry, fetching performance indicators failed.', 'woocommerce' ) ); - } - - foreach ( $endpoints as $endpoint ) { - if ( '/stats' === substr( $endpoint['slug'], -6 ) ) { - $request = new \WP_REST_Request( 'OPTIONS', $endpoint['path'] ); - $response = rest_do_request( $request ); - $data = $response->get_data(); - - $prefix = substr( $endpoint['slug'], 0, -6 ); - - if ( empty( $data['schema']['properties']['totals']['properties'] ) ) { - continue; - } - - foreach ( $data['schema']['properties']['totals']['properties'] as $property_key => $schema_info ) { - if ( empty( $schema_info['indicator'] ) || ! $schema_info['indicator'] ) { - continue; - } - - $stat = $prefix . '/' . $property_key; - $allowed_stats[] = $stat; - - $this->labels[ $stat ] = trim( preg_replace( '/\W+/', ' ', $schema_info['description'] ) ); - $this->formats[ $stat ] = isset( $schema_info['format'] ) ? $schema_info['format'] : 'number'; - } - - $this->endpoints[ $prefix ] = $endpoint['path']; - $this->urls[ $prefix ] = $endpoint['_links']['report'][0]['href']; - } - } - - $this->allowed_stats = $allowed_stats; - return true; - } - - /** - * Returns a list of allowed performance indicators. - * - * @param \WP_REST_Request $request Request data. - * @return array|\WP_Error - */ - public function get_allowed_items( $request ) { - $indicator_data = $this->get_indicator_data(); - if ( is_wp_error( $indicator_data ) ) { - return $indicator_data; - } - - $data = array(); - foreach ( $this->allowed_stats as $stat ) { - $pieces = $this->get_stats_parts( $stat ); - $report = $pieces[0]; - $chart = $pieces[1]; - $data[] = (object) array( - 'stat' => $stat, - 'chart' => $chart, - 'label' => $this->labels[ $stat ], - ); - } - - usort( $data, array( $this, 'sort' ) ); - - $objects = array(); - foreach ( $data as $item ) { - $prepared = $this->prepare_item_for_response( $item, $request ); - $objects[] = $this->prepare_response_for_collection( $prepared ); - } - - $response = rest_ensure_response( $objects ); - $response->header( 'X-WP-Total', count( $data ) ); - $response->header( 'X-WP-TotalPages', 1 ); - - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - - return $response; - } - - /** - * Sorts the list of stats. Sorted by custom arrangement. - * - * @see https://github.com/woocommerce/woocommerce-admin/issues/1282 - * @param object $a First item. - * @param object $b Second item. - * @return order - */ - public function sort( $a, $b ) { - /** - * Custom ordering for store performance indicators. - * - * @see https://github.com/woocommerce/woocommerce-admin/issues/1282 - * @param array $indicators A list of ordered indicators. - */ - $stat_order = apply_filters( - 'woocommerce_rest_report_sort_performance_indicators', - array( - 'revenue/gross_revenue', - 'revenue/net_revenue', - 'orders/orders_count', - 'orders/avg_order_value', - 'products/items_sold', - 'revenue/refunds', - 'coupons/orders_count', - 'coupons/amount', - 'taxes/total_tax', - 'taxes/order_tax', - 'taxes/shipping_tax', - 'revenue/shipping', - 'downloads/download_count', - ) - ); - - $a = array_search( $a->stat, $stat_order ); - $b = array_search( $b->stat, $stat_order ); - - if ( false === $a && false === $b ) { - return 0; - } elseif ( false === $a ) { - return 1; - } elseif ( false === $b ) { - return -1; - } else { - return $a - $b; - } - } - - /** - * Get all reports. - * - * @param \WP_REST_Request $request Request data. - * @return array|\WP_Error - */ - public function get_items( $request ) { - $indicator_data = $this->get_indicator_data(); - if ( is_wp_error( $indicator_data ) ) { - return $indicator_data; - } - - $query_args = $this->prepare_reports_query( $request ); - if ( empty( $query_args['stats'] ) ) { - return new \WP_Error( 'woocommerce_reports_performance_indicators_empty_query', __( 'A list of stats to query must be provided.', 'woocommerce' ), 400 ); - } - - $stats = array(); - foreach ( $query_args['stats'] as $stat ) { - $is_error = false; - - $pieces = $this->get_stats_parts( $stat ); - $report = $pieces[0]; - $chart = $pieces[1]; - - if ( ! in_array( $stat, $this->allowed_stats ) ) { - continue; - } - - $request_url = $this->endpoints[ $report ]; - $request = new \WP_REST_Request( 'GET', $request_url ); - $request->set_param( 'before', $query_args['before'] ); - $request->set_param( 'after', $query_args['after'] ); - - $response = rest_do_request( $request ); - - $data = $response->get_data(); - $format = $this->formats[ $stat ]; - $label = $this->labels[ $stat ]; - - if ( 200 !== $response->get_status() || ! isset( $data['totals'][ $chart ] ) ) { - $stats[] = (object) array( - 'stat' => $stat, - 'chart' => $chart, - 'label' => $label, - 'format' => $format, - 'value' => null, - ); - continue; - } - - $stats[] = (object) array( - 'stat' => $stat, - 'chart' => $chart, - 'label' => $label, - 'format' => $format, - 'value' => $data['totals'][ $chart ], - ); - } - - usort( $stats, array( $this, 'sort' ) ); - - $objects = array(); - foreach ( $stats as $stat ) { - $data = $this->prepare_item_for_response( $stat, $request ); - $objects[] = $this->prepare_response_for_collection( $data ); - } - - $response = rest_ensure_response( $objects ); - $response->header( 'X-WP-Total', count( $stats ) ); - $response->header( 'X-WP-TotalPages', 1 ); - - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $stat_data Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $stat_data, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $stat_data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $data ) ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_performance_indicators', $response, $stat_data, $request ); - } - - /** - * Prepare links for the request. - * - * @param WC_Admin_Reports_Query $object Object data. - * @return array - */ - protected function prepare_links( $object ) { - $pieces = $this->get_stats_parts( $object->stat ); - $endpoint = $pieces[0]; - $stat = $pieces[1]; - $url = $this->urls[ $endpoint ]; - - $links = array( - 'api' => array( - 'href' => rest_url( $this->endpoints[ $endpoint ] ), - ), - 'report' => array( - 'href' => ! empty( $url ) ? $url : '', - ), - ); - - return $links; - } - - /** - * Returns the endpoint part of a stat request (prefix) and the actual stat total we want. - * To allow extensions to namespace (example: fue/emails/sent), we break on the last forward slash. - * - * @param string $full_stat A stat request string like orders/avg_order_value or fue/emails/sent. - * @return array Containing the prefix (endpoint) and suffix (stat). - */ - private function get_stats_parts( $full_stat ) { - $endpoint = substr( $full_stat, 0, strrpos( $full_stat, '/' ) ); - $stat = substr( $full_stat, ( strrpos( $full_stat, '/' ) + 1 ) ); - return array( - $endpoint, - $stat, - ); - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $indicator_data = $this->get_indicator_data(); - if ( is_wp_error( $indicator_data ) ) { - $allowed_stats = array(); - } else { - $allowed_stats = $this->allowed_stats; - } - - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_performance_indicator', - 'type' => 'object', - 'properties' => array( - 'stat' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'enum' => $allowed_stats, - ), - 'chart' => array( - 'description' => __( 'The specific chart this stat referrers to.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'Human readable label for the stat.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'format' => array( - 'description' => __( 'Format of the stat.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'enum' => array( 'number', 'currency' ), - ), - 'value' => array( - 'description' => __( 'Value of the stat. Returns null if the stat does not exist or cannot be loaded.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get schema for the list of allowed performance indicators. - * - * @return array $schema - */ - public function get_public_allowed_item_schema() { - $schema = $this->get_public_item_schema(); - unset( $schema['properties']['value'] ); - unset( $schema['properties']['format'] ); - return $schema; - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $indicator_data = $this->get_indicator_data(); - if ( is_wp_error( $indicator_data ) ) { - $allowed_stats = __( 'There was an issue loading the report endpoints', 'woocommerce' ); - } else { - $allowed_stats = implode( ', ', $this->allowed_stats ); - } - - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['stats'] = array( - 'description' => sprintf( - /* translators: Allowed values is a list of stat endpoints. */ - __( 'Limit response to specific report stats. Allowed values: %s.', 'woocommerce' ), - $allowed_stats - ), - 'type' => 'array', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'string', - ), - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/ProductStats.php b/src/Controllers/Version4/Reports/ProductStats.php deleted file mode 100644 index caceed9698a..00000000000 --- a/src/Controllers/Version4/Reports/ProductStats.php +++ /dev/null @@ -1,410 +0,0 @@ - 'product_includes', - ); - - /** - * Constructor. - */ - public function __construct() { - add_filter( 'woocommerce_reports_products_stats_select_query', array( $this, 'set_default_report_data' ) ); - } - - /** - * Get all reports. - * - * @param \WP_REST_Request $request Request data. - * @return array|\WP_Error - */ - public function get_items( $request ) { - $query_args = array( - 'fields' => array( - 'items_sold', - 'net_revenue', - 'orders_count', - 'products_count', - 'variations_count', - ), - ); - - $registered = array_keys( $this->get_collection_params() ); - foreach ( $registered as $param_name ) { - if ( isset( $request[ $param_name ] ) ) { - if ( isset( $this->param_mapping[ $param_name ] ) ) { - $query_args[ $this->param_mapping[ $param_name ] ] = $request[ $param_name ]; - } else { - $query_args[ $param_name ] = $request[ $param_name ]; - } - } - } - - $query = new \WC_Admin_Reports_Products_Stats_Query( $query_args ); - try { - $report_data = $query->get_data(); - } catch ( \WC_Admin_Reports_Parameter_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - - $out_data = array( - 'totals' => get_object_vars( $report_data->totals ), - 'intervals' => array(), - ); - - foreach ( $report_data->intervals as $interval_data ) { - $item = $this->prepare_item_for_response( $interval_data, $request ); - $out_data['intervals'][] = $this->prepare_response_for_collection( $item ); - } - - $response = rest_ensure_response( $out_data ); - $response->header( 'X-WP-Total', (int) $report_data->total ); - $response->header( 'X-WP-TotalPages', (int) $report_data->pages ); - - $page = $report_data->page_no; - $max_pages = $report_data->pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param Array $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $data = $report; - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_products_stats', $response, $report, $request ); - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $data_values = array( - 'items_sold' => array( - 'description' => __( 'Number of items sold.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'indicator' => true, - ), - 'net_revenue' => array( - 'description' => __( 'Net revenue.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'format' => 'currency', - ), - 'orders_count' => array( - 'description' => __( 'Number of orders.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ); - - $segments = array( - 'segments' => array( - 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'segment_id' => array( - 'description' => __( 'Segment identificator.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'segment_label' => array( - 'description' => __( 'Human readable segment label, either product or variation name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'enum' => array( 'day', 'week', 'month', 'year' ), - ), - 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $data_values, - ), - ), - ), - ), - ); - - $totals = array_merge( $data_values, $segments ); - - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_products_stats', - 'type' => 'object', - 'properties' => array( - 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $totals, - ), - 'intervals' => array( - 'description' => __( 'Reports data grouped by intervals.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'interval' => array( - 'description' => __( 'Type of interval.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'enum' => array( 'day', 'week', 'month', 'year' ), - ), - 'date_start' => array( - 'description' => __( "The date the report start, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_start_gmt' => array( - 'description' => __( 'The date the report start, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_end' => array( - 'description' => __( "The date the report end, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_end_gmt' => array( - 'description' => __( 'The date the report end, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $totals, - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Set the default results to 0 if API returns an empty array - * - * @param Mixed $results Report data. - * @return object - */ - public function set_default_report_data( $results ) { - if ( empty( $results ) ) { - $results = new \stdClass(); - $results->total = 0; - $results->totals = new \stdClass(); - $results->totals->items_sold = 0; - $results->totals->net_revenue = 0; - $results->totals->orders_count = 0; - $results->intervals = array(); - $results->pages = 1; - $results->page_no = 1; - } - return $results; - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'net_revenue', - 'coupons', - 'refunds', - 'shipping', - 'taxes', - 'net_revenue', - 'orders_count', - 'items_sold', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['interval'] = array( - 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'week', - 'enum' => array( - 'hour', - 'day', - 'week', - 'month', - 'quarter', - 'year', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['categories'] = array( - 'description' => __( 'Limit result to items from the specified categories.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['products'] = array( - 'description' => __( 'Limit result to items with specified product ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['variations'] = array( - 'description' => __( 'Limit result to items with specified variation ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['segmentby'] = array( - 'description' => __( 'Segment the response by additional constraint.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array( - 'product', - 'category', - 'variation', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/Products.php b/src/Controllers/Version4/Reports/Products.php deleted file mode 100644 index fd91702dbc7..00000000000 --- a/src/Controllers/Version4/Reports/Products.php +++ /dev/null @@ -1,338 +0,0 @@ - 'product_includes', - ); - - /** - * Get items. - * - * @param \WP_REST_Request $request Request data. - * - * @return array|\WP_Error - */ - public function get_items( $request ) { - $args = array(); - $registered = array_keys( $this->get_collection_params() ); - foreach ( $registered as $param_name ) { - if ( isset( $request[ $param_name ] ) ) { - if ( isset( $this->param_mapping[ $param_name ] ) ) { - $args[ $this->param_mapping[ $param_name ] ] = $request[ $param_name ]; - } else { - $args[ $param_name ] = $request[ $param_name ]; - } - } - } - - $reports = new \WC_Admin_Reports_Products_Query( $args ); - $products_data = $reports->get_data(); - - $data = array(); - - foreach ( $products_data->data as $product_data ) { - $item = $this->prepare_item_for_response( $product_data, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - $response = rest_ensure_response( $data ); - $response->header( 'X-WP-Total', (int) $products_data->total ); - $response->header( 'X-WP-TotalPages', (int) $products_data->pages ); - - $page = $products_data->page_no; - $max_pages = $products_data->pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param Array $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $data = $report; - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $report ) ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_products', $response, $report, $request ); - } - - /** - * Prepare links for the request. - * - * @param Array $object Object data. - * @return array Links for the given post. - */ - protected function prepare_links( $object ) { - $links = array( - 'product' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, 'products', $object['product_id'] ) ), - ), - ); - - return $links; - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_products', - 'type' => 'object', - 'properties' => array( - 'product_id' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product ID.', 'woocommerce' ), - ), - 'items_sold' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Number of items sold.', 'woocommerce' ), - ), - 'net_revenue' => array( - 'type' => 'number', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Total net revenue of all items sold.', 'woocommerce' ), - ), - 'orders_count' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Number of orders product appeared in.', 'woocommerce' ), - ), - 'extended_info' => array( - 'name' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product name.', 'woocommerce' ), - ), - 'price' => array( - 'type' => 'number', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product price.', 'woocommerce' ), - ), - 'image' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product image.', 'woocommerce' ), - ), - 'permalink' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product link.', 'woocommerce' ), - ), - 'attributes' => array( - 'type' => 'array', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product attributes.', 'woocommerce' ), - ), - 'stock_status' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product inventory status.', 'woocommerce' ), - ), - 'stock_quantity' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product inventory quantity.', 'woocommerce' ), - ), - 'low_stock_amount' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product inventory threshold for low stock.', 'woocommerce' ), - ), - 'variations' => array( - 'type' => 'array', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product variations IDs.', 'woocommerce' ), - ), - 'sku' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product SKU.', 'woocommerce' ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'net_revenue', - 'orders_count', - 'items_sold', - 'product_name', - 'variations', - 'sku', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['categories'] = array( - 'description' => __( 'Limit result to items from the specified categories.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $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', 'woocommerce' ), - 'type' => 'string', - 'default' => 'all', - 'enum' => array( - 'all', - 'any', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['products'] = array( - 'description' => __( 'Limit result to items with specified product ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - - ); - $params['extended_info'] = array( - 'description' => __( 'Add additional piece of info about each product to the report.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'sanitize_callback' => 'wc_string_to_bool', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/RevenueStats.php b/src/Controllers/Version4/Reports/RevenueStats.php deleted file mode 100644 index 50608095a0f..00000000000 --- a/src/Controllers/Version4/Reports/RevenueStats.php +++ /dev/null @@ -1,396 +0,0 @@ -prepare_reports_query( $request ); - $reports_revenue = new \WC_Admin_Reports_Revenue_Query( $query_args ); - try { - $report_data = $reports_revenue->get_data(); - } catch ( WC_Admin_Reports_Parameter_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - - $out_data = array( - 'totals' => get_object_vars( $report_data->totals ), - 'intervals' => array(), - ); - - foreach ( $report_data->intervals as $interval_data ) { - $item = $this->prepare_item_for_response( $interval_data, $request ); - $out_data['intervals'][] = $this->prepare_response_for_collection( $item ); - } - - $response = rest_ensure_response( $out_data ); - $response->header( 'X-WP-Total', (int) $report_data->total ); - $response->header( 'X-WP-TotalPages', (int) $report_data->pages ); - - $page = $report_data->page_no; - $max_pages = $report_data->pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param Array $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $data = $report; - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_revenue_stats', $response, $report, $request ); - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $data_values = array( - 'gross_revenue' => array( - 'description' => __( 'Gross revenue.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'indicator' => true, - 'format' => 'currency', - ), - 'net_revenue' => array( - 'description' => __( 'Net revenue.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'indicator' => true, - 'format' => 'currency', - ), - 'coupons' => array( - 'description' => __( 'Amount discounted by coupons.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'coupons_count' => array( - 'description' => __( 'Unique coupons count.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'format' => 'currency', - ), - 'shipping' => array( - 'description' => __( 'Total of shipping.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'indicator' => true, - 'format' => 'currency', - ), - 'taxes' => array( - 'description' => __( 'Total of taxes.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'format' => 'currency', - ), - 'refunds' => array( - 'description' => __( 'Total of refunds.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'indicator' => true, - 'format' => 'currency', - ), - 'orders_count' => array( - 'description' => __( 'Amount of orders.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'num_items_sold' => array( - 'description' => __( 'Items sold.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'products' => array( - 'description' => __( 'Products sold.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ); - - $segments = array( - 'segments' => array( - 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'segment_id' => array( - 'description' => __( 'Segment identificator.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $data_values, - ), - ), - ), - ), - ); - - $totals = array_merge( $data_values, $segments ); - - // Products is not shown in intervals. - unset( $data_values['products'] ); - - $intervals = array_merge( $data_values, $segments ); - - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_revenue_stats', - 'type' => 'object', - 'properties' => array( - 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $totals, - ), - 'intervals' => array( - 'description' => __( 'Reports data grouped by intervals.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'interval' => array( - 'description' => __( 'Type of interval.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'enum' => array( 'day', 'week', 'month', 'year' ), - ), - 'date_start' => array( - 'description' => __( "The date the report start, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_start_gmt' => array( - 'description' => __( 'The date the report start, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_end' => array( - 'description' => __( "The date the report end, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_end_gmt' => array( - 'description' => __( 'The date the report end, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $intervals, - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'gross_revenue', - 'coupons', - 'refunds', - 'shipping', - 'taxes', - 'net_revenue', - 'orders_count', - 'items_sold', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['interval'] = array( - 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'week', - 'enum' => array( - 'hour', - 'day', - 'week', - 'month', - 'quarter', - 'year', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['segmentby'] = array( - 'description' => __( 'Segment the response by additional constraint.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array( - 'product', - 'category', - 'variation', - 'coupon', - 'customer_type', // new vs returning. - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/Stock.php b/src/Controllers/Version4/Reports/Stock.php deleted file mode 100644 index ab9b601b5bc..00000000000 --- a/src/Controllers/Version4/Reports/Stock.php +++ /dev/null @@ -1,413 +0,0 @@ - 'AND', - '_stock_status' => array( - 'key' => '_stock_status', - 'compare' => 'EXISTS', - ), - '_stock' => array( - 'key' => '_stock', - 'compare' => 'EXISTS', - 'type' => 'NUMERIC', - ), - ); - $args['orderby'] = array( - '_stock_status' => $args['order'], - '_stock' => 'desc' === $args['order'] ? 'asc' : 'desc', - ); - } elseif ( 'stock_quantity' === $args['orderby'] ) { - $args['meta_key'] = '_stock'; // WPCS: slow query ok. - $args['orderby'] = 'meta_value_num'; - } elseif ( 'include' === $args['orderby'] ) { - $args['orderby'] = 'post__in'; - } elseif ( 'id' === $args['orderby'] ) { - $args['orderby'] = 'ID'; // ID must be capitalized. - } elseif ( 'sku' === $args['orderby'] ) { - $args['meta_key'] = '_sku'; // WPCS: slow query ok. - $args['orderby'] = 'meta_value'; - } - - $args['post_type'] = array( 'product', 'product_variation' ); - - if ( 'lowstock' === $request['type'] ) { - $low_stock = absint( max( get_option( 'woocommerce_notify_low_stock_amount' ), 1 ) ); - $no_stock = absint( max( get_option( 'woocommerce_notify_no_stock_amount' ), 0 ) ); - - $args['meta_query'] = array( // WPCS: slow query ok. - array( - 'key' => '_manage_stock', - 'value' => 'yes', - ), - array( - 'key' => '_stock', - 'value' => array( $no_stock, $low_stock ), - 'compare' => 'BETWEEN', - 'type' => 'NUMERIC', - ), - array( - 'key' => '_stock_status', - 'value' => 'instock', - ), - ); - } elseif ( in_array( $request['type'], array_keys( wc_get_product_stock_status_options() ), true ) ) { - $args['meta_query'] = array( // WPCS: slow query ok. - array( - 'key' => '_stock_status', - 'value' => $request['type'], - ), - ); - } - - $query_args['ignore_sticky_posts'] = true; - - return $args; - } - - /** - * Query products. - * - * @param array $query_args Query args. - * @return array - */ - protected function get_products( $query_args ) { - $query = new \WP_Query(); - $result = $query->query( $query_args ); - - $total_posts = $query->found_posts; - if ( $total_posts < 1 ) { - // Out-of-bounds, run the query again without LIMIT for total count. - unset( $query_args['paged'] ); - $count_query = new \WP_Query(); - $count_query->query( $query_args ); - $total_posts = $count_query->found_posts; - } - - return array( - 'objects' => array_map( 'wc_get_product', $result ), - 'total' => (int) $total_posts, - 'pages' => (int) ceil( $total_posts / (int) $query->query_vars['posts_per_page'] ), - ); - } - - /** - * Get all reports. - * - * @param \WP_REST_Request $request Request data. - * @return array|\WP_Error - */ - public function get_items( $request ) { - $query_args = $this->prepare_reports_query( $request ); - $query_results = $this->get_products( $query_args ); - - $objects = array(); - foreach ( $query_results['objects'] as $object ) { - $data = $this->prepare_item_for_response( $object, $request ); - $objects[] = $this->prepare_response_for_collection( $data ); - } - - $page = (int) $query_args['paged']; - $max_pages = $query_results['pages']; - - $response = rest_ensure_response( $objects ); - $response->header( 'X-WP-Total', $query_results['total'] ); - $response->header( 'X-WP-TotalPages', (int) $max_pages ); - - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param WC_Product $product Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $product, $request ) { - $data = array( - 'id' => $product->get_id(), - 'parent_id' => $product->get_parent_id(), - 'name' => $product->get_name(), - 'sku' => $product->get_sku(), - 'stock_status' => $product->get_stock_status(), - 'stock_quantity' => (float) $product->get_stock_quantity(), - 'manage_stock' => $product->get_manage_stock(), - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $product ) ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param WC_Product $product The original product object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_stock', $response, $product, $request ); - } - - /** - * Prepare links for the request. - * - * @param WC_Product $product Object data. - * @return array - */ - protected function prepare_links( $product ) { - if ( $product->is_type( 'variation' ) ) { - $links = array( - 'product' => array( - 'href' => rest_url( sprintf( '/%s/products/%d/variations/%d', $this->namespace, $product->get_parent_id(), $product->get_id() ) ), - ), - 'parent' => array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product->get_parent_id() ) ), - ), - ); - } elseif ( $product->get_parent_id() ) { - $links = array( - 'product' => array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product->get_id() ) ), - ), - 'parent' => array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product->get_parent_id() ) ), - ), - ); - } else { - $links = array( - 'product' => array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product->get_id() ) ), - ), - ); - } - - return $links; - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_stock', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'stock_status' => array( - 'description' => __( 'Stock status.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'manage_stock' => array( - 'description' => __( 'Manage stock.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'sanitize_callback' => 'wp_parse_id_list', - ); - $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'sanitize_callback' => 'wp_parse_id_list', - ); - $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'asc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'stock_status', - 'enum' => array( - 'stock_status', - 'stock_quantity', - 'date', - 'id', - 'include', - 'title', - 'sku', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['parent'] = array( - 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'sanitize_callback' => 'wp_parse_id_list', - 'default' => array(), - ); - $params['parent_exclude'] = array( - 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'sanitize_callback' => 'wp_parse_id_list', - 'default' => array(), - ); - $params['type'] = array( - 'description' => __( 'Limit result set to items assigned a stock report type.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'all', - 'enum' => array_merge( array( 'all', 'lowstock' ), array_keys( wc_get_product_stock_status_options() ) ), - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/StockStats.php b/src/Controllers/Version4/Reports/StockStats.php deleted file mode 100644 index 625f3788abf..00000000000 --- a/src/Controllers/Version4/Reports/StockStats.php +++ /dev/null @@ -1,132 +0,0 @@ -get_data(); - $out_data = array( - 'totals' => $report_data, - ); - return rest_ensure_response( $out_data ); - } - - /** - * Prepare a report object for serialization. - * - * @param WC_Product $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $data = $report; - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param WC_Product $product The original bject. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_stock_stats', $response, $product, $request ); - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $totals = array( - 'products' => array( - 'description' => __( 'Number of products.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'lowstock' => array( - 'description' => __( 'Number of low stock products.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ); - - $status_options = wc_get_product_stock_status_options(); - foreach ( $status_options as $status => $label ) { - $totals[ $status ] = array( - /* translators: Stock status. Example: "Number of low stock products */ - 'description' => sprintf( __( 'Number of %s products.', 'woocommerce' ), $label ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ); - } - - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_customers_stats', - 'type' => 'object', - 'properties' => array( - 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $totals, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/TaxStats.php b/src/Controllers/Version4/Reports/TaxStats.php deleted file mode 100644 index 5fc4c61963d..00000000000 --- a/src/Controllers/Version4/Reports/TaxStats.php +++ /dev/null @@ -1,385 +0,0 @@ -total = 0; - $results->totals = new \stdClass(); - $results->totals->tax_codes = 0; - $results->totals->total_tax = 0; - $results->totals->order_tax = 0; - $results->totals->shipping_tax = 0; - $results->totals->orders = 0; - $results->intervals = array(); - $results->pages = 1; - $results->page_no = 1; - } - return $results; - } - - /** - * Maps query arguments from the REST request. - * - * @param array $request Request array. - * @return array - */ - protected function prepare_reports_query( $request ) { - $args = array(); - $args['before'] = $request['before']; - $args['after'] = $request['after']; - $args['interval'] = $request['interval']; - $args['page'] = $request['page']; - $args['per_page'] = $request['per_page']; - $args['orderby'] = $request['orderby']; - $args['order'] = $request['order']; - $args['taxes'] = (array) $request['taxes']; - $args['segmentby'] = $request['segmentby']; - - return $args; - } - - /** - * Get all reports. - * - * @param \WP_REST_Request $request Request data. - * @return array|\WP_Error - */ - public function get_items( $request ) { - $query_args = $this->prepare_reports_query( $request ); - $taxes_query = new \WC_Admin_Reports_Taxes_Stats_Query( $query_args ); - $report_data = $taxes_query->get_data(); - - $out_data = array( - 'totals' => get_object_vars( $report_data->totals ), - 'intervals' => array(), - ); - - foreach ( $report_data->intervals as $interval_data ) { - $item = $this->prepare_item_for_response( (object) $interval_data, $request ); - $out_data['intervals'][] = $this->prepare_response_for_collection( $item ); - } - - $response = rest_ensure_response( $out_data ); - $response->header( 'X-WP-Total', (int) $report_data->total ); - $response->header( 'X-WP-TotalPages', (int) $report_data->pages ); - - $page = $report_data->page_no; - $max_pages = $report_data->pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $data = get_object_vars( $report ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_taxes_stats', $response, $report, $request ); - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $data_values = array( - 'total_tax' => array( - 'description' => __( 'Total tax.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'indicator' => true, - 'format' => 'currency', - ), - 'order_tax' => array( - 'description' => __( 'Order tax.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'indicator' => true, - 'format' => 'currency', - ), - 'shipping_tax' => array( - 'description' => __( 'Shipping tax.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'indicator' => true, - 'format' => 'currency', - ), - 'orders_count' => array( - 'description' => __( 'Amount of orders.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tax_codes' => array( - 'description' => __( 'Amount of tax codes.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ); - - $segments = array( - 'segments' => array( - 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'segment_id' => array( - 'description' => __( 'Segment identificator.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $data_values, - ), - ), - ), - ), - ); - - $totals = array_merge( $data_values, $segments ); - - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_taxes_stats', - 'type' => 'object', - 'properties' => array( - 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $totals, - ), - 'intervals' => array( - 'description' => __( 'Reports data grouped by intervals.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'interval' => array( - 'description' => __( 'Type of interval.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'enum' => array( 'day', 'week', 'month', 'year' ), - ), - 'date_start' => array( - 'description' => __( "The date the report start, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_start_gmt' => array( - 'description' => __( 'The date the report start, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_end' => array( - 'description' => __( "The date the report end, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_end_gmt' => array( - 'description' => __( 'The date the report end, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $totals, - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'items_sold', - 'gross_revenue', - 'orders_count', - 'products_count', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['interval'] = array( - 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'week', - 'enum' => array( - 'hour', - 'day', - 'week', - 'month', - 'quarter', - 'year', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['taxes'] = array( - 'description' => __( 'Limit result set to all items that have the specified term assigned in the taxes taxonomy.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['segmentby'] = array( - 'description' => __( 'Segment the response by additional constraint.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array( - 'tax_rate_id', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/Taxes.php b/src/Controllers/Version4/Reports/Taxes.php deleted file mode 100644 index f19b99944d9..00000000000 --- a/src/Controllers/Version4/Reports/Taxes.php +++ /dev/null @@ -1,282 +0,0 @@ -prepare_reports_query( $request ); - $taxes_query = new \WC_Admin_Reports_Taxes_Query( $query_args ); - $report_data = $taxes_query->get_data(); - - $data = array(); - - foreach ( $report_data->data as $tax_data ) { - $item = $this->prepare_item_for_response( (object) $tax_data, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - $response = rest_ensure_response( $data ); - $response->header( 'X-WP-Total', (int) $report_data->total ); - $response->header( 'X-WP-TotalPages', (int) $report_data->pages ); - - $page = $report_data->page_no; - $max_pages = $report_data->pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $report = $this->add_additional_fields_to_object( $report, $request ); - $report = $this->filter_response_by_context( $report, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $report ); - $response->add_links( $this->prepare_links( $report ) ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_taxes', $response, $report, $request ); - } - - /** - * Prepare links for the request. - * - * @param WC_Reports_Query $object Object data. - * @return array - */ - protected function prepare_links( $object ) { - $links = array( - 'tax' => array( - 'href' => rest_url( sprintf( '/%s/taxes/%d', $this->namespace, $object->tax_rate_id ) ), - ), - ); - - return $links; - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_taxes', - 'type' => 'object', - 'properties' => array( - 'tax_rate_id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Tax rate name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tax_rate' => array( - 'description' => __( 'Tax rate.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'country' => array( - 'description' => __( 'Country.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'state' => array( - 'description' => __( 'State.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'priority' => array( - 'description' => __( 'Priority.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_tax' => array( - 'description' => __( 'Total tax.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'order_tax' => array( - 'description' => __( 'Order tax.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_tax' => array( - 'description' => __( 'Shipping tax.', 'woocommerce' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'orders_count' => array( - 'description' => __( 'Amount of orders.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'tax_rate_id', - 'enum' => array( - 'name', - 'tax_rate_id', - 'tax_code', - 'rate', - 'order_tax', - 'total_tax', - 'shipping_tax', - 'orders_count', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['taxes'] = array( - 'description' => __( 'Limit result set to items assigned one or more tax rates.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'string', - ), - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Reports/Variations.php b/src/Controllers/Version4/Reports/Variations.php deleted file mode 100644 index 63a1f6c86ad..00000000000 --- a/src/Controllers/Version4/Reports/Variations.php +++ /dev/null @@ -1,322 +0,0 @@ - 'product_includes', - ); - - /** - * Get items. - * - * @param \WP_REST_Request $request Request data. - * - * @return array|\WP_Error - */ - public function get_items( $request ) { - $args = array(); - $registered = array_keys( $this->get_collection_params() ); - foreach ( $registered as $param_name ) { - if ( isset( $request[ $param_name ] ) ) { - if ( isset( $this->param_mapping[ $param_name ] ) ) { - $args[ $this->param_mapping[ $param_name ] ] = $request[ $param_name ]; - } else { - $args[ $param_name ] = $request[ $param_name ]; - } - } - } - - $reports = new \WC_Admin_Reports_Variations_Query( $args ); - $products_data = $reports->get_data(); - - $data = array(); - - foreach ( $products_data->data as $product_data ) { - $item = $this->prepare_item_for_response( $product_data, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - $response = rest_ensure_response( $data ); - $response->header( 'X-WP-Total', (int) $products_data->total ); - $response->header( 'X-WP-TotalPages', (int) $products_data->pages ); - - $page = $products_data->page_no; - $max_pages = $products_data->pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Prepare a report object for serialization. - * - * @param array $report Report data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $report, $request ) { - $data = $report; - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $report ) ); - - /** - * Filter a report returned from the API. - * - * Allows modification of the report data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $report The original report object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_variations', $response, $report, $request ); - } - - /** - * Prepare links for the request. - * - * @param array $object Object data. - * @return array Links for the given post. - */ - protected function prepare_links( $object ) { - $links = array( - 'product' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, 'products', $object['product_id'] ) ), - ), - 'variation' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d/%s/%d', $this->namespace, 'products', $object['product_id'], 'variation', $object['variation_id'] ) ), - ), - ); - - return $links; - } - - /** - * Get the Report's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'report_varitations', - 'type' => 'object', - 'properties' => array( - 'product_id' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product ID.', 'woocommerce' ), - ), - 'variation_id' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product ID.', 'woocommerce' ), - ), - 'items_sold' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Number of items sold.', 'woocommerce' ), - ), - 'net_revenue' => array( - 'type' => 'number', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Total net revenue of all items sold.', 'woocommerce' ), - ), - 'orders_count' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Number of orders product appeared in.', 'woocommerce' ), - ), - 'extended_info' => array( - 'name' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product name.', 'woocommerce' ), - ), - 'price' => array( - 'type' => 'number', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product price.', 'woocommerce' ), - ), - 'image' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product image.', 'woocommerce' ), - ), - 'permalink' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product link.', 'woocommerce' ), - ), - 'attributes' => array( - 'type' => 'array', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product attributes.', 'woocommerce' ), - ), - 'stock_status' => array( - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product inventory status.', 'woocommerce' ), - ), - 'stock_quantity' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product inventory quantity.', 'woocommerce' ), - ), - 'low_stock_amount' => array( - 'type' => 'integer', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product inventory threshold for low stock.', 'woocommerce' ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), - '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' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['before'] = array( - 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'net_revenue', - 'orders_count', - 'items_sold', - 'sku', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['products'] = array( - 'description' => __( 'Limit result to items with specified product ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['variations'] = array( - 'description' => __( 'Limit result to items with specified variation ids.', 'woocommerce' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['extended_info'] = array( - 'description' => __( 'Add additional piece of info about each product to the report.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'sanitize_callback' => 'wc_string_to_bool', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/_changelog.md b/src/Controllers/Version4/_changelog.md index e510d46c08c..c66a8effa6e 100644 --- a/src/Controllers/Version4/_changelog.md +++ b/src/Controllers/Version4/_changelog.md @@ -16,27 +16,7 @@ ## New endpoints -- `reports/products` -- `reports/products/stats` -- `reports/categories` -- `reports/orders` -- `reports/orders/stats` -- `reports/performance-indicators` -- `reports/revenue/stats` -- `reports/stock` -- `reports/stock/stats` -- `reports/taxes` -- `reports/taxes/stats` -- `reports/variations` -- `reports/coupons` -- `reports/coupons/stats` -- `reports/customer` -- `reports/customers/stats` -- `reports/downloads` -- `reports/downloads/stats` -- `reports/import` - `data/download-ips` -- `leaderboards` ## Removed endpoints diff --git a/src/Server.php b/src/Server.php index 11a58b05630..307d7a6dd19 100644 --- a/src/Server.php +++ b/src/Server.php @@ -202,7 +202,6 @@ class Server { 'data-countries' => $namespace . 'Data\Countries', 'data-currencies' => $namespace . 'Data\Currencies', 'data-download-ips' => $namespace . 'Data\DownloadIPs', - 'leaderboards' => $namespace . 'Leaderboards', 'network-orders' => $namespace . 'NetworkOrders', 'order-notes' => $namespace . 'OrderNotes', 'order-refunds' => $namespace . 'OrderRefunds', @@ -216,7 +215,6 @@ class Server { 'product-shipping-classes' => $namespace . 'ProductShippingClasses', 'product-tags' => $namespace . 'ProductTags', 'product-variations' => $namespace . 'ProductVariations', - 'reports' => $namespace . 'Reports', 'settings' => $namespace . 'Settings', 'settings-options' => $namespace . 'SettingsOptions', 'shipping-methods' => $namespace . 'ShippingMethods', @@ -230,32 +228,6 @@ class Server { 'webhooks' => $namespace . 'Webhooks', ]; - if ( class_exists( '\WC_Admin_Note' ) ) { - $controllers['admin-notes'] = $namespace . 'AdminNotes'; - } - - if ( class_exists( '\WC_Admin_Reports_Sync' ) ) { - $controllers['reports-categories'] = $namespace . 'Reports\Categories'; - $controllers['reports-coupons'] = $namespace . 'Reports\Coupons'; - $controllers['reports-coupon-stats'] = $namespace . 'Reports\CouponStats'; - $controllers['reports-customers'] = $namespace . 'Reports\Customers'; - $controllers['reports-customer-stats'] = $namespace . 'Reports\CustomerStats'; - $controllers['reports-downloads'] = $namespace . 'Reports\Downloads'; - $controllers['reports-download-stats'] = $namespace . 'Reports\DownloadStats'; - $controllers['reports-import'] = $namespace . 'Reports\Import'; - $controllers['reports-orders'] = $namespace . 'Reports\Orders'; - $controllers['reports-order-stats'] = $namespace . 'Reports\OrderStats'; - $controllers['reports-performance-indicators'] = $namespace . 'Reports\PerformanceIndicators'; - $controllers['reports-products'] = $namespace . 'Reports\Products'; - $controllers['reports-product-stats'] = $namespace . 'Reports\ProductStats'; - $controllers['reports-revenue-stats'] = $namespace . 'Reports\RevenueStats'; - $controllers['reports-stock'] = $namespace . 'Reports\Stock'; - $controllers['reports-stock-stats'] = $namespace . 'Reports\StockStats'; - $controllers['reports-taxes'] = $namespace . 'Reports\Taxes'; - $controllers['reports-tax-stats'] = $namespace . 'Reports\TaxStats'; - $controllers['reports-variations'] = $namespace . 'Reports\Variations'; - } - return $controllers; } }